Adding support for service account credentials.

- Tested end to end with a JSON key I generated for my account using the
fetch_oauth2 binary.
- The same fetch_oauth2 binary can get a token from the GCE metadata service on a VM in cloud.
	Change on 2014/12/19 by jboeuf <jboeuf@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=82548689
diff --git a/Makefile b/Makefile
index 049d1f8..cbf1f23 100644
--- a/Makefile
+++ b/Makefile
@@ -622,7 +622,7 @@
 	$(Q) ./bins/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
 
 
-tools: privatelibs bins/gen_hpack_tables
+tools: privatelibs bins/gen_hpack_tables bins/grpc_fetch_oauth2
 
 protoc_plugins: bins/cpp_plugin bins/ruby_plugin
 
@@ -731,7 +731,7 @@
 
 dep_c: deps_libgpr deps_libgrpc deps_libgrpc_test_util deps_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request deps_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs deps_libgrpc_unsecure
 
-bins_dep_c: deps_gen_hpack_tables deps_grpc_byte_buffer_reader_test deps_gpr_cancellable_test deps_gpr_log_test deps_gpr_useful_test deps_gpr_cmdline_test deps_gpr_histogram_test deps_gpr_host_port_test deps_gpr_slice_buffer_test deps_gpr_slice_test deps_gpr_string_test deps_gpr_sync_test deps_gpr_thd_test deps_gpr_time_test deps_murmur_hash_test deps_grpc_stream_op_test deps_alpn_test deps_time_averaged_stats_test deps_chttp2_stream_encoder_test deps_hpack_table_test deps_chttp2_stream_map_test deps_hpack_parser_test deps_transport_metadata_test deps_chttp2_status_conversion_test deps_chttp2_transport_end2end_test deps_tcp_posix_test deps_dualstack_socket_test deps_no_server_test deps_resolve_address_test deps_sockaddr_utils_test deps_tcp_server_posix_test deps_tcp_client_posix_test deps_grpc_channel_stack_test deps_metadata_buffer_test deps_grpc_completion_queue_test deps_grpc_completion_queue_benchmark deps_census_window_stats_test deps_census_statistics_quick_test deps_census_statistics_small_log_test deps_census_statistics_performance_test deps_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test deps_census_hash_table_test deps_fling_server deps_fling_client deps_fling_test deps_echo_server deps_echo_client deps_echo_test deps_low_level_ping_pong_benchmark deps_message_compress_test deps_bin_encoder_test deps_secure_endpoint_test deps_httpcli_format_request_test deps_httpcli_parser_test deps_httpcli_test deps_grpc_credentials_test deps_grpc_base64_test deps_grpc_json_token_test deps_timeout_encoding_test deps_fd_posix_test deps_fling_stream_test deps_lame_client_test deps_alarm_test deps_time_test deps_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+bins_dep_c: deps_gen_hpack_tables deps_grpc_byte_buffer_reader_test deps_gpr_cancellable_test deps_gpr_log_test deps_gpr_useful_test deps_gpr_cmdline_test deps_gpr_histogram_test deps_gpr_host_port_test deps_gpr_slice_buffer_test deps_gpr_slice_test deps_gpr_string_test deps_gpr_sync_test deps_gpr_thd_test deps_gpr_time_test deps_murmur_hash_test deps_grpc_stream_op_test deps_alpn_test deps_time_averaged_stats_test deps_chttp2_stream_encoder_test deps_hpack_table_test deps_chttp2_stream_map_test deps_hpack_parser_test deps_transport_metadata_test deps_chttp2_status_conversion_test deps_chttp2_transport_end2end_test deps_tcp_posix_test deps_dualstack_socket_test deps_no_server_test deps_resolve_address_test deps_sockaddr_utils_test deps_tcp_server_posix_test deps_tcp_client_posix_test deps_grpc_channel_stack_test deps_metadata_buffer_test deps_grpc_completion_queue_test deps_grpc_completion_queue_benchmark deps_census_window_stats_test deps_census_statistics_quick_test deps_census_statistics_small_log_test deps_census_statistics_performance_test deps_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test deps_census_hash_table_test deps_fling_server deps_fling_client deps_fling_test deps_echo_server deps_echo_client deps_echo_test deps_low_level_ping_pong_benchmark deps_message_compress_test deps_bin_encoder_test deps_secure_endpoint_test deps_httpcli_format_request_test deps_httpcli_parser_test deps_httpcli_test deps_grpc_credentials_test deps_grpc_fetch_oauth2 deps_grpc_base64_test deps_grpc_json_token_test deps_timeout_encoding_test deps_fd_posix_test deps_fling_stream_test deps_lame_client_test deps_alarm_test deps_time_test deps_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
 
 dep_cxx: deps_libgrpc++ deps_libgrpc++_test_util
 
@@ -779,7 +779,7 @@
 	$(E) "[INSTALL] Installing libgrpc++.so"
 	$(Q) $(INSTALL) libs/libgrpc++.so.$(VERSION) $(prefix)/lib/libgrpc++.so.$(VERSION)
 
-clean: clean_libgpr clean_libgrpc clean_libgrpc_test_util clean_libgrpc++ clean_libgrpc++_test_util clean_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_disappearing_server clean_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_invoke_large_request clean_libend2end_test_max_concurrent_streams clean_libend2end_test_no_op clean_libend2end_test_ping_pong_streaming clean_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_simple_delayed_request clean_libend2end_test_simple_request clean_libend2end_test_thread_stress clean_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_certs clean_libgrpc_unsecure clean_gen_hpack_tables clean_cpp_plugin clean_ruby_plugin clean_grpc_byte_buffer_reader_test clean_gpr_cancellable_test clean_gpr_log_test clean_gpr_useful_test clean_gpr_cmdline_test clean_gpr_histogram_test clean_gpr_host_port_test clean_gpr_slice_buffer_test clean_gpr_slice_test clean_gpr_string_test clean_gpr_sync_test clean_gpr_thd_test clean_gpr_time_test clean_murmur_hash_test clean_grpc_stream_op_test clean_alpn_test clean_time_averaged_stats_test clean_chttp2_stream_encoder_test clean_hpack_table_test clean_chttp2_stream_map_test clean_hpack_parser_test clean_transport_metadata_test clean_chttp2_status_conversion_test clean_chttp2_transport_end2end_test clean_tcp_posix_test clean_dualstack_socket_test clean_no_server_test clean_resolve_address_test clean_sockaddr_utils_test clean_tcp_server_posix_test clean_tcp_client_posix_test clean_grpc_channel_stack_test clean_metadata_buffer_test clean_grpc_completion_queue_test clean_grpc_completion_queue_benchmark clean_census_window_stats_test clean_census_statistics_quick_test clean_census_statistics_small_log_test clean_census_statistics_performance_test clean_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_circular_buffer_test clean_census_stub_test clean_census_hash_table_test clean_fling_server clean_fling_client clean_fling_test clean_echo_server clean_echo_client clean_echo_test clean_low_level_ping_pong_benchmark clean_message_compress_test clean_bin_encoder_test clean_secure_endpoint_test clean_httpcli_format_request_test clean_httpcli_parser_test clean_httpcli_test clean_grpc_credentials_test clean_grpc_base64_test clean_grpc_json_token_test clean_timeout_encoding_test clean_fd_posix_test clean_fling_stream_test clean_lame_client_test clean_thread_pool_test clean_status_test clean_sync_client_async_server_test clean_qps_client clean_qps_server clean_interop_server clean_interop_client clean_end2end_test clean_channel_arguments_test clean_alarm_test clean_time_test clean_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_no_op_test clean_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_no_op_test clean_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+clean: clean_libgpr clean_libgrpc clean_libgrpc_test_util clean_libgrpc++ clean_libgrpc++_test_util clean_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_disappearing_server clean_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_invoke_large_request clean_libend2end_test_max_concurrent_streams clean_libend2end_test_no_op clean_libend2end_test_ping_pong_streaming clean_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_simple_delayed_request clean_libend2end_test_simple_request clean_libend2end_test_thread_stress clean_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_certs clean_libgrpc_unsecure clean_gen_hpack_tables clean_cpp_plugin clean_ruby_plugin clean_grpc_byte_buffer_reader_test clean_gpr_cancellable_test clean_gpr_log_test clean_gpr_useful_test clean_gpr_cmdline_test clean_gpr_histogram_test clean_gpr_host_port_test clean_gpr_slice_buffer_test clean_gpr_slice_test clean_gpr_string_test clean_gpr_sync_test clean_gpr_thd_test clean_gpr_time_test clean_murmur_hash_test clean_grpc_stream_op_test clean_alpn_test clean_time_averaged_stats_test clean_chttp2_stream_encoder_test clean_hpack_table_test clean_chttp2_stream_map_test clean_hpack_parser_test clean_transport_metadata_test clean_chttp2_status_conversion_test clean_chttp2_transport_end2end_test clean_tcp_posix_test clean_dualstack_socket_test clean_no_server_test clean_resolve_address_test clean_sockaddr_utils_test clean_tcp_server_posix_test clean_tcp_client_posix_test clean_grpc_channel_stack_test clean_metadata_buffer_test clean_grpc_completion_queue_test clean_grpc_completion_queue_benchmark clean_census_window_stats_test clean_census_statistics_quick_test clean_census_statistics_small_log_test clean_census_statistics_performance_test clean_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_circular_buffer_test clean_census_stub_test clean_census_hash_table_test clean_fling_server clean_fling_client clean_fling_test clean_echo_server clean_echo_client clean_echo_test clean_low_level_ping_pong_benchmark clean_message_compress_test clean_bin_encoder_test clean_secure_endpoint_test clean_httpcli_format_request_test clean_httpcli_parser_test clean_httpcli_test clean_grpc_credentials_test clean_grpc_fetch_oauth2 clean_grpc_base64_test clean_grpc_json_token_test clean_timeout_encoding_test clean_fd_posix_test clean_fling_stream_test clean_lame_client_test clean_thread_pool_test clean_status_test clean_sync_client_async_server_test clean_qps_client clean_qps_server clean_interop_server clean_interop_client clean_end2end_test clean_channel_arguments_test clean_alarm_test clean_time_test clean_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_no_op_test clean_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_no_op_test clean_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
 	$(Q) $(RM) -r deps objs libs bins gens
 
 
@@ -4137,6 +4137,40 @@
 	$(Q) $(RM) bins/grpc_credentials_test
 
 
+GRPC_FETCH_OAUTH2_SRC = \
+    test/core/security/fetch_oauth2.c \
+
+GRPC_FETCH_OAUTH2_OBJS = $(addprefix objs/, $(addsuffix .o, $(basename $(GRPC_FETCH_OAUTH2_SRC))))
+GRPC_FETCH_OAUTH2_DEPS = $(addprefix deps/, $(addsuffix .dep, $(basename $(GRPC_FETCH_OAUTH2_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/grpc_fetch_oauth2: openssl_dep_error
+
+else
+
+bins/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) libs/libgrpc_test_util.a libs/libgrpc.a libs/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) -Llibs -lgrpc_test_util -lgrpc -lgpr $(LDLIBS) $(LDLIBS_SECURE) -o bins/grpc_fetch_oauth2
+
+endif
+
+deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_FETCH_OAUTH2_DEPS)
+endif
+endif
+
+clean_grpc_fetch_oauth2:
+	$(E) "[CLEAN]   Cleaning grpc_fetch_oauth2 files"
+	$(Q) $(RM) $(GRPC_FETCH_OAUTH2_OBJS)
+	$(Q) $(RM) $(GRPC_FETCH_OAUTH2_DEPS)
+	$(Q) $(RM) bins/grpc_fetch_oauth2
+
+
 GRPC_BASE64_TEST_SRC = \
     test/core/security/base64_test.c \
 
@@ -8691,4 +8725,4 @@
 
 
 
-.PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx clean dep_c dep_cxx bins_dep_c bins_dep_cxx deps_libgpr clean_libgpr deps_libgrpc clean_libgrpc deps_libgrpc_test_util clean_libgrpc_test_util deps_libgrpc++ clean_libgrpc++ deps_libgrpc++_test_util clean_libgrpc++_test_util deps_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server clean_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request clean_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams clean_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op clean_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming clean_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request clean_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request clean_libend2end_test_simple_request deps_libend2end_test_thread_stress clean_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs clean_libend2end_certs deps_libgrpc_unsecure clean_libgrpc_unsecure deps_gen_hpack_tables clean_gen_hpack_tables deps_cpp_plugin clean_cpp_plugin deps_ruby_plugin clean_ruby_plugin deps_grpc_byte_buffer_reader_test clean_grpc_byte_buffer_reader_test deps_gpr_cancellable_test clean_gpr_cancellable_test deps_gpr_log_test clean_gpr_log_test deps_gpr_useful_test clean_gpr_useful_test deps_gpr_cmdline_test clean_gpr_cmdline_test deps_gpr_histogram_test clean_gpr_histogram_test deps_gpr_host_port_test clean_gpr_host_port_test deps_gpr_slice_buffer_test clean_gpr_slice_buffer_test deps_gpr_slice_test clean_gpr_slice_test deps_gpr_string_test clean_gpr_string_test deps_gpr_sync_test clean_gpr_sync_test deps_gpr_thd_test clean_gpr_thd_test deps_gpr_time_test clean_gpr_time_test deps_murmur_hash_test clean_murmur_hash_test deps_grpc_stream_op_test clean_grpc_stream_op_test deps_alpn_test clean_alpn_test deps_time_averaged_stats_test clean_time_averaged_stats_test deps_chttp2_stream_encoder_test clean_chttp2_stream_encoder_test deps_hpack_table_test clean_hpack_table_test deps_chttp2_stream_map_test clean_chttp2_stream_map_test deps_hpack_parser_test clean_hpack_parser_test deps_transport_metadata_test clean_transport_metadata_test deps_chttp2_status_conversion_test clean_chttp2_status_conversion_test deps_chttp2_transport_end2end_test clean_chttp2_transport_end2end_test deps_tcp_posix_test clean_tcp_posix_test deps_dualstack_socket_test clean_dualstack_socket_test deps_no_server_test clean_no_server_test deps_resolve_address_test clean_resolve_address_test deps_sockaddr_utils_test clean_sockaddr_utils_test deps_tcp_server_posix_test clean_tcp_server_posix_test deps_tcp_client_posix_test clean_tcp_client_posix_test deps_grpc_channel_stack_test clean_grpc_channel_stack_test deps_metadata_buffer_test clean_metadata_buffer_test deps_grpc_completion_queue_test clean_grpc_completion_queue_test deps_grpc_completion_queue_benchmark clean_grpc_completion_queue_benchmark deps_census_window_stats_test clean_census_window_stats_test deps_census_statistics_quick_test clean_census_statistics_quick_test deps_census_statistics_small_log_test clean_census_statistics_small_log_test deps_census_statistics_performance_test clean_census_statistics_performance_test deps_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test clean_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test clean_census_stub_test deps_census_hash_table_test clean_census_hash_table_test deps_fling_server clean_fling_server deps_fling_client clean_fling_client deps_fling_test clean_fling_test deps_echo_server clean_echo_server deps_echo_client clean_echo_client deps_echo_test clean_echo_test deps_low_level_ping_pong_benchmark clean_low_level_ping_pong_benchmark deps_message_compress_test clean_message_compress_test deps_bin_encoder_test clean_bin_encoder_test deps_secure_endpoint_test clean_secure_endpoint_test deps_httpcli_format_request_test clean_httpcli_format_request_test deps_httpcli_parser_test clean_httpcli_parser_test deps_httpcli_test clean_httpcli_test deps_grpc_credentials_test clean_grpc_credentials_test deps_grpc_base64_test clean_grpc_base64_test deps_grpc_json_token_test clean_grpc_json_token_test deps_timeout_encoding_test clean_timeout_encoding_test deps_fd_posix_test clean_fd_posix_test deps_fling_stream_test clean_fling_stream_test deps_lame_client_test clean_lame_client_test deps_thread_pool_test clean_thread_pool_test deps_status_test clean_status_test deps_sync_client_async_server_test clean_sync_client_async_server_test deps_qps_client clean_qps_client deps_qps_server clean_qps_server deps_interop_server clean_interop_server deps_interop_client clean_interop_client deps_end2end_test clean_end2end_test deps_channel_arguments_test clean_channel_arguments_test deps_alarm_test clean_alarm_test deps_time_test clean_time_test deps_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test clean_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test clean_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+.PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx clean dep_c dep_cxx bins_dep_c bins_dep_cxx deps_libgpr clean_libgpr deps_libgrpc clean_libgrpc deps_libgrpc_test_util clean_libgrpc_test_util deps_libgrpc++ clean_libgrpc++ deps_libgrpc++_test_util clean_libgrpc++_test_util deps_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server clean_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request clean_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams clean_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op clean_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming clean_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request clean_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request clean_libend2end_test_simple_request deps_libend2end_test_thread_stress clean_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs clean_libend2end_certs deps_libgrpc_unsecure clean_libgrpc_unsecure deps_gen_hpack_tables clean_gen_hpack_tables deps_cpp_plugin clean_cpp_plugin deps_ruby_plugin clean_ruby_plugin deps_grpc_byte_buffer_reader_test clean_grpc_byte_buffer_reader_test deps_gpr_cancellable_test clean_gpr_cancellable_test deps_gpr_log_test clean_gpr_log_test deps_gpr_useful_test clean_gpr_useful_test deps_gpr_cmdline_test clean_gpr_cmdline_test deps_gpr_histogram_test clean_gpr_histogram_test deps_gpr_host_port_test clean_gpr_host_port_test deps_gpr_slice_buffer_test clean_gpr_slice_buffer_test deps_gpr_slice_test clean_gpr_slice_test deps_gpr_string_test clean_gpr_string_test deps_gpr_sync_test clean_gpr_sync_test deps_gpr_thd_test clean_gpr_thd_test deps_gpr_time_test clean_gpr_time_test deps_murmur_hash_test clean_murmur_hash_test deps_grpc_stream_op_test clean_grpc_stream_op_test deps_alpn_test clean_alpn_test deps_time_averaged_stats_test clean_time_averaged_stats_test deps_chttp2_stream_encoder_test clean_chttp2_stream_encoder_test deps_hpack_table_test clean_hpack_table_test deps_chttp2_stream_map_test clean_chttp2_stream_map_test deps_hpack_parser_test clean_hpack_parser_test deps_transport_metadata_test clean_transport_metadata_test deps_chttp2_status_conversion_test clean_chttp2_status_conversion_test deps_chttp2_transport_end2end_test clean_chttp2_transport_end2end_test deps_tcp_posix_test clean_tcp_posix_test deps_dualstack_socket_test clean_dualstack_socket_test deps_no_server_test clean_no_server_test deps_resolve_address_test clean_resolve_address_test deps_sockaddr_utils_test clean_sockaddr_utils_test deps_tcp_server_posix_test clean_tcp_server_posix_test deps_tcp_client_posix_test clean_tcp_client_posix_test deps_grpc_channel_stack_test clean_grpc_channel_stack_test deps_metadata_buffer_test clean_metadata_buffer_test deps_grpc_completion_queue_test clean_grpc_completion_queue_test deps_grpc_completion_queue_benchmark clean_grpc_completion_queue_benchmark deps_census_window_stats_test clean_census_window_stats_test deps_census_statistics_quick_test clean_census_statistics_quick_test deps_census_statistics_small_log_test clean_census_statistics_small_log_test deps_census_statistics_performance_test clean_census_statistics_performance_test deps_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test clean_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test clean_census_stub_test deps_census_hash_table_test clean_census_hash_table_test deps_fling_server clean_fling_server deps_fling_client clean_fling_client deps_fling_test clean_fling_test deps_echo_server clean_echo_server deps_echo_client clean_echo_client deps_echo_test clean_echo_test deps_low_level_ping_pong_benchmark clean_low_level_ping_pong_benchmark deps_message_compress_test clean_message_compress_test deps_bin_encoder_test clean_bin_encoder_test deps_secure_endpoint_test clean_secure_endpoint_test deps_httpcli_format_request_test clean_httpcli_format_request_test deps_httpcli_parser_test clean_httpcli_parser_test deps_httpcli_test clean_httpcli_test deps_grpc_credentials_test clean_grpc_credentials_test deps_grpc_fetch_oauth2 clean_grpc_fetch_oauth2 deps_grpc_base64_test clean_grpc_base64_test deps_grpc_json_token_test clean_grpc_json_token_test deps_timeout_encoding_test clean_timeout_encoding_test deps_fd_posix_test clean_fd_posix_test deps_fling_stream_test clean_fling_stream_test deps_lame_client_test clean_lame_client_test deps_thread_pool_test clean_thread_pool_test deps_status_test clean_status_test deps_sync_client_async_server_test clean_sync_client_async_server_test deps_qps_client clean_qps_client deps_qps_server clean_qps_server deps_interop_server clean_interop_server deps_interop_client clean_interop_client deps_end2end_test clean_end2end_test deps_channel_arguments_test clean_channel_arguments_test deps_alarm_test clean_alarm_test deps_time_test clean_time_test deps_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test clean_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test clean_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
diff --git a/build.json b/build.json
index dc64378..50f3ca3 100644
--- a/build.json
+++ b/build.json
@@ -1088,6 +1088,18 @@
       ]
     },
     {
+      "name": "grpc_fetch_oauth2",
+      "build": "tool",
+      "src": [
+        "test/core/security/fetch_oauth2.c"
+      ],
+      "deps": [
+        "grpc_test_util",
+        "grpc",
+        "gpr"
+      ]
+    },
+    {
       "name": "grpc_base64_test",
       "build": "test",
       "src": [
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index bfc2e33..442d2fa 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -35,6 +35,7 @@
 
 #include "src/core/httpcli/httpcli.h"
 #include "src/core/iomgr/iomgr.h"
+#include "src/core/security/json_token.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string.h>
@@ -47,10 +48,18 @@
 #include <stdio.h>
 
 /* -- Constants. -- */
-#define GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS 60
+
+#define GRPC_OAUTH2_TOKEN_REFRESH_THRESHOLD_SECS 60
+
 #define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
 #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
-  "computeMetadata/v1/instance/service-accounts/default/token"
+  "/computeMetadata/v1/instance/service-accounts/default/token"
+
+#define GRPC_SERVICE_ACCOUNT_HOST "www.googleapis.com"
+#define GRPC_SERVICE_ACCOUNT_TOKEN_PATH "/oauth2/v3/token"
+#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX                         \
+  "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \
+  "assertion="
 
 /* -- Common. -- */
 
@@ -234,7 +243,14 @@
   return &c->base;
 }
 
-/* -- ComputeEngine credentials. -- */
+/* -- Oauth2TokenFetcher credentials -- */
+
+/* This object is a base for credentials that need to acquire an oauth2 token
+   from an http service. */
+
+typedef void (*grpc_fetch_oauth2_func)(grpc_credentials_metadata_request *req,
+                                       grpc_httpcli_response_cb response_cb,
+                                       gpr_timespec deadline);
 
 typedef struct {
   grpc_credentials base;
@@ -242,10 +258,12 @@
   grpc_mdctx *md_ctx;
   grpc_mdelem *access_token_md;
   gpr_timespec token_expiration;
-} grpc_compute_engine_credentials;
+  grpc_fetch_oauth2_func fetch_func;
+} grpc_oauth2_token_fetcher_credentials;
 
-static void compute_engine_destroy(grpc_credentials *creds) {
-  grpc_compute_engine_credentials *c = (grpc_compute_engine_credentials *)creds;
+static void oauth2_token_fetcher_destroy(grpc_credentials *creds) {
+  grpc_oauth2_token_fetcher_credentials *c =
+      (grpc_oauth2_token_fetcher_credentials *)creds;
   if (c->access_token_md != NULL) {
     grpc_mdelem_unref(c->access_token_md);
   }
@@ -254,16 +272,18 @@
   gpr_free(c);
 }
 
-static int compute_engine_has_request_metadata(const grpc_credentials *creds) {
-  return 1;
-}
-
-static int compute_engine_has_request_metadata_only(
+static int oauth2_token_fetcher_has_request_metadata(
     const grpc_credentials *creds) {
   return 1;
 }
 
-grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
+static int oauth2_token_fetcher_has_request_metadata_only(
+    const grpc_credentials *creds) {
+  return 1;
+}
+
+grpc_credentials_status
+grpc_oauth2_token_fetcher_credentials_parse_server_response(
     const grpc_httpcli_response *response, grpc_mdctx *ctx,
     grpc_mdelem **token_elem, gpr_timespec *token_lifetime) {
   char *null_terminated_body = NULL;
@@ -271,9 +291,16 @@
   grpc_credentials_status status = GRPC_CREDENTIALS_OK;
   cJSON *json = NULL;
 
+  if (response->body_length > 0) {
+    null_terminated_body = gpr_malloc(response->body_length + 1);
+    null_terminated_body[response->body_length] = '\0';
+    memcpy(null_terminated_body, response->body, response->body_length);
+  }
+
   if (response->status != 200) {
-    gpr_log(GPR_ERROR, "Call to metadata server ended with error %d",
-            response->status);
+    gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].",
+            response->status,
+            null_terminated_body != NULL ? null_terminated_body : "");
     status = GRPC_CREDENTIALS_ERROR;
     goto end;
   } else {
@@ -281,9 +308,6 @@
     cJSON *token_type = NULL;
     cJSON *expires_in = NULL;
     size_t new_access_token_size = 0;
-    null_terminated_body = gpr_malloc(response->body_length + 1);
-    null_terminated_body[response->body_length] = '\0';
-    memcpy(null_terminated_body, response->body, response->body_length);
     json = cJSON_Parse(null_terminated_body);
     if (json == NULL) {
       gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body);
@@ -338,17 +362,17 @@
   return status;
 }
 
-static void on_compute_engine_token_response(
+static void on_oauth2_token_fetcher_http_response(
     void *user_data, const grpc_httpcli_response *response) {
   grpc_credentials_metadata_request *r =
       (grpc_credentials_metadata_request *)user_data;
-  grpc_compute_engine_credentials *c =
-      (grpc_compute_engine_credentials *)r->creds;
+  grpc_oauth2_token_fetcher_credentials *c =
+      (grpc_oauth2_token_fetcher_credentials *)r->creds;
   gpr_timespec token_lifetime;
   grpc_credentials_status status;
 
   gpr_mu_lock(&c->mu);
-  status = grpc_compute_engine_credentials_parse_server_response(
+  status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
       response, c->md_ctx, &c->access_token_md, &token_lifetime);
   if (status == GRPC_CREDENTIALS_OK) {
     c->token_expiration = gpr_time_add(gpr_now(), token_lifetime);
@@ -361,51 +385,149 @@
   grpc_credentials_metadata_request_destroy(r);
 }
 
-static void compute_engine_get_request_metadata(grpc_credentials *creds,
-                                                grpc_credentials_metadata_cb cb,
-                                                void *user_data) {
-  grpc_compute_engine_credentials *c = (grpc_compute_engine_credentials *)creds;
-  gpr_timespec refresh_threshold = {
-      GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS, 0};
-
-  gpr_mu_lock(&c->mu);
-  if (c->access_token_md == NULL ||
-      (gpr_time_cmp(gpr_time_sub(gpr_now(), c->token_expiration),
-                    refresh_threshold) < 0)) {
-    grpc_httpcli_header header = {"Metadata-Flavor", "Google"};
-    grpc_httpcli_request request;
-    request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
-    request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
-    request.hdr_count = 1;
-    request.hdrs = &header;
-    grpc_httpcli_get(
-        &request, gpr_time_add(gpr_now(), refresh_threshold),
-        on_compute_engine_token_response,
-        grpc_credentials_metadata_request_create(creds, cb, user_data));
-  } else {
-    cb(user_data, &c->access_token_md, 1, GRPC_CREDENTIALS_OK);
+static void oauth2_token_fetcher_get_request_metadata(
+    grpc_credentials *creds, grpc_credentials_metadata_cb cb, void *user_data) {
+  grpc_oauth2_token_fetcher_credentials *c =
+      (grpc_oauth2_token_fetcher_credentials *)creds;
+  gpr_timespec refresh_threshold = {GRPC_OAUTH2_TOKEN_REFRESH_THRESHOLD_SECS,
+                                    0};
+  grpc_mdelem *cached_access_token_md = NULL;
+  {
+    gpr_mu_lock(&c->mu);
+    if (c->access_token_md != NULL &&
+        (gpr_time_cmp(gpr_time_sub(c->token_expiration, gpr_now()),
+                      refresh_threshold) > 0)) {
+      cached_access_token_md = grpc_mdelem_ref(c->access_token_md);
+    }
+    gpr_mu_unlock(&c->mu);
   }
-  gpr_mu_unlock(&c->mu);
+  if (cached_access_token_md != NULL) {
+    cb(user_data, &cached_access_token_md, 1, GRPC_CREDENTIALS_OK);
+    grpc_mdelem_unref(cached_access_token_md);
+  } else {
+    c->fetch_func(
+        grpc_credentials_metadata_request_create(creds, cb, user_data),
+        on_oauth2_token_fetcher_http_response,
+        gpr_time_add(gpr_now(), refresh_threshold));
+  }
 }
 
-static grpc_credentials_vtable compute_engine_vtable = {
-    compute_engine_destroy, compute_engine_has_request_metadata,
-    compute_engine_has_request_metadata_only,
-    compute_engine_get_request_metadata};
-
-grpc_credentials *grpc_compute_engine_credentials_create(void) {
-  grpc_compute_engine_credentials *c =
-      gpr_malloc(sizeof(grpc_compute_engine_credentials));
-  memset(c, 0, sizeof(grpc_compute_engine_credentials));
+static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
+                                      grpc_fetch_oauth2_func fetch_func) {
+  memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
   c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
-  c->base.vtable = &compute_engine_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   gpr_mu_init(&c->mu);
   c->md_ctx = grpc_mdctx_create();
   c->token_expiration = gpr_inf_past;
+  c->fetch_func = fetch_func;
+}
+
+/* -- ComputeEngine credentials. -- */
+
+static grpc_credentials_vtable compute_engine_vtable = {
+    oauth2_token_fetcher_destroy, oauth2_token_fetcher_has_request_metadata,
+    oauth2_token_fetcher_has_request_metadata_only,
+    oauth2_token_fetcher_get_request_metadata};
+
+static void compute_engine_fetch_oauth2(
+    grpc_credentials_metadata_request *metadata_req,
+    grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
+  grpc_httpcli_header header = {"Metadata-Flavor", "Google"};
+  grpc_httpcli_request request;
+  memset(&request, 0, sizeof(grpc_httpcli_request));
+  request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
+  request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
+  request.hdr_count = 1;
+  request.hdrs = &header;
+  grpc_httpcli_get(&request, deadline, response_cb, metadata_req);
+}
+
+grpc_credentials *grpc_compute_engine_credentials_create(void) {
+  grpc_oauth2_token_fetcher_credentials *c =
+      gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
+  init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
+  c->base.vtable = &compute_engine_vtable;
   return &c->base;
 }
 
+/* -- ServiceAccount credentials. -- */
+
+typedef struct {
+  grpc_oauth2_token_fetcher_credentials base;
+  grpc_auth_json_key key;
+  char *scope;
+  gpr_timespec token_lifetime;
+} grpc_service_account_credentials;
+
+static void service_account_destroy(grpc_credentials *creds) {
+  grpc_service_account_credentials *c =
+      (grpc_service_account_credentials *)creds;
+  if (c->scope != NULL) gpr_free(c->scope);
+  grpc_auth_json_key_destruct(&c->key);
+  oauth2_token_fetcher_destroy(&c->base.base);
+}
+
+static grpc_credentials_vtable service_account_vtable = {
+    service_account_destroy, oauth2_token_fetcher_has_request_metadata,
+    oauth2_token_fetcher_has_request_metadata_only,
+    oauth2_token_fetcher_get_request_metadata};
+
+static void service_account_fetch_oauth2(
+    grpc_credentials_metadata_request *metadata_req,
+    grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
+  grpc_service_account_credentials *c =
+      (grpc_service_account_credentials *)metadata_req->creds;
+  grpc_httpcli_header header = {"Content-Type",
+                                "application/x-www-form-urlencoded"};
+  grpc_httpcli_request request;
+  char *body = NULL;
+  char *jwt = grpc_jwt_encode_and_sign(&c->key, c->scope, c->token_lifetime);
+  if (jwt == NULL) {
+    grpc_httpcli_response response;
+    memset(&response, 0, sizeof(grpc_httpcli_response));
+    response.status = 400; /* Invalid request. */
+    gpr_log(GPR_ERROR, "Could not create signed jwt.");
+    /* Do not even send the request, just call the response callback. */
+    response_cb(metadata_req, &response);
+    return;
+  }
+  body = gpr_malloc(strlen(GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX) +
+                    strlen(jwt) + 1);
+  sprintf(body, "%s%s", GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX, jwt);
+  memset(&request, 0, sizeof(grpc_httpcli_request));
+  request.host = GRPC_SERVICE_ACCOUNT_HOST;
+  request.path = GRPC_SERVICE_ACCOUNT_TOKEN_PATH;
+  request.hdr_count = 1;
+  request.hdrs = &header;
+  request.use_ssl = 1;
+  grpc_httpcli_post(&request, body, strlen(body), deadline, response_cb,
+                    metadata_req);
+  gpr_free(body);
+  gpr_free(jwt);
+}
+
+grpc_credentials *grpc_service_account_credentials_create(
+    const char *json_key, const char *scope, gpr_timespec token_lifetime) {
+  grpc_service_account_credentials *c;
+  grpc_auth_json_key key = grpc_auth_json_key_create_from_string(json_key);
+
+  if (scope == NULL || (strlen(scope) == 0) ||
+      !grpc_auth_json_key_is_valid(&key)) {
+    gpr_log(GPR_ERROR,
+            "Invalid input for service account credentials creation");
+    return NULL;
+  }
+  c = gpr_malloc(sizeof(grpc_service_account_credentials));
+  memset(c, 0, sizeof(grpc_service_account_credentials));
+  init_oauth2_token_fetcher(&c->base, service_account_fetch_oauth2);
+  c->base.base.vtable = &service_account_vtable;
+  c->scope = gpr_strdup(scope);
+  c->key = key;
+  c->token_lifetime = token_lifetime;
+  return &c->base.base;
+}
+
 /* -- Fake Oauth2 credentials. -- */
 
 typedef struct {
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 9fb82e1..036a444 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -109,7 +109,8 @@
     grpc_credentials *composite_creds);
 
 /* Exposed for testing only. */
-grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
+grpc_credentials_status
+grpc_oauth2_token_fetcher_credentials_parse_server_response(
     const struct grpc_httpcli_response *response, grpc_mdctx *ctx,
     grpc_mdelem **token_elem, gpr_timespec *token_lifetime);
 
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 440dd8a..14ee758 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -58,6 +58,10 @@
 #define GRPC_JWT_RSA_SHA256_ALGORITHM "RS256"
 #define GRPC_JWT_TYPE "JWT"
 
+/* --- Override for testing. --- */
+
+static grpc_jwt_encode_and_sign_override g_jwt_encode_and_sign_override = NULL;
+
 /* --- grpc_auth_json_key. --- */
 
 static const char *json_get_string_property(cJSON *json,
@@ -79,7 +83,7 @@
   return 1;
 }
 
-int grpc_auth_json_key_is_valid(grpc_auth_json_key *json_key) {
+int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) {
   return (json_key != NULL) &&
          strcmp(json_key->type, GRPC_AUTH_JSON_KEY_TYPE_INVALID);
 }
@@ -277,14 +281,23 @@
 
 char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key,
                                const char *scope, gpr_timespec token_lifetime) {
-  const char *sig_algo = GRPC_JWT_RSA_SHA256_ALGORITHM;
-  char *to_sign = dot_concat_and_free_strings(
-      encoded_jwt_header(sig_algo),
-      encoded_jwt_claim(json_key, scope, token_lifetime));
-  char *sig = compute_and_encode_signature(json_key, sig_algo, to_sign);
-  if (sig == NULL) {
-    gpr_free(to_sign);
-    return NULL;
+  if (g_jwt_encode_and_sign_override != NULL) {
+    return g_jwt_encode_and_sign_override(json_key, scope, token_lifetime);
+  } else {
+    const char *sig_algo = GRPC_JWT_RSA_SHA256_ALGORITHM;
+    char *to_sign = dot_concat_and_free_strings(
+        encoded_jwt_header(sig_algo),
+        encoded_jwt_claim(json_key, scope, token_lifetime));
+    char *sig = compute_and_encode_signature(json_key, sig_algo, to_sign);
+    if (sig == NULL) {
+      gpr_free(to_sign);
+      return NULL;
+    }
+    return dot_concat_and_free_strings(to_sign, sig);
   }
-  return dot_concat_and_free_strings(to_sign, sig);
+}
+
+void grpc_jwt_encode_and_sign_set_override(
+    grpc_jwt_encode_and_sign_override func) {
+  g_jwt_encode_and_sign_override = func;
 }
diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h
index 2a1f825..3ef9f1b 100644
--- a/src/core/security/json_token.h
+++ b/src/core/security/json_token.h
@@ -37,7 +37,7 @@
 #include <grpc/support/slice.h>
 #include <openssl/rsa.h>
 
-/* --- auth_json_key parsing. Exposed for testing only. --- */
+/* --- auth_json_key parsing. --- */
 
 typedef struct {
   char *type;
@@ -48,7 +48,7 @@
 } grpc_auth_json_key;
 
 /* Returns 1 if the object is valid, 0 otherwise. */
-int grpc_auth_json_key_is_valid(grpc_auth_json_key *json_key);
+int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key);
 
 /* Creates a json_key object from string. Returns an invalid object if a parsing
    error has been encountered. */
@@ -65,4 +65,13 @@
 char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key,
                                const char *scope, gpr_timespec token_lifetime);
 
+/* Override encode_and_sign function for testing. */
+typedef char *(*grpc_jwt_encode_and_sign_override)(
+    const grpc_auth_json_key *json_key, const char *scope,
+    gpr_timespec token_lifetime);
+
+/* Set a custom encode_and_sign override for testing. */
+void grpc_jwt_encode_and_sign_set_override(
+    grpc_jwt_encode_and_sign_override func);
+
 #endif /* __GRPC_INTERNAL_SECURITY_JSON_TOKEN_H_ */
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 7eca844..619f093 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -33,12 +33,16 @@
 
 #include "src/core/security/credentials.h"
 
+#include <string.h>
+
 #include "src/core/httpcli/httpcli.h"
+#include "src/core/security/json_token.h"
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string.h>
 #include <grpc/support/time.h>
 #include "test/core/util/test_config.h"
-
-#include <string.h>
+#include <openssl/rsa.h>
 
 static const char test_iam_authorization_token[] = "blahblahblhahb";
 static const char test_iam_authority_selector[] = "respectmyauthoritah";
@@ -46,30 +50,86 @@
     "Bearer blaaslkdjfaslkdfasdsfasf";
 static const unsigned char test_root_cert[] = {0xDE, 0xAD, 0xBE, 0xEF};
 
+/* This JSON key was generated with the GCE console and revoked immediately.
+   The identifiers have been changed as well.
+   Maximum size for a string literal is 509 chars in C89, yay!  */
+static const char test_json_key_str_part1[] =
+    "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
+    "\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\n7mJEqg"
+    "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\nyjSeg/"
+    "rWBQvS4hle4LfijkP3J5BG+"
+    "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\nOnVF6N7dL3nTYZg+"
+    "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\nDZgSE6Bu/"
+    "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\n/"
+    "8HpCqFYM9V8f34SBWfD4fRFT+n/"
+    "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\ngqXjDvpkypEusgXAykECQQD+";
+static const char test_json_key_str_part2[] =
+    "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\nCslxoHQM8s+"
+    "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\nEkoy2L/"
+    "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\nAARh2QJBAMKeDAG"
+    "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\n8FZi5c8idxiwC36kbAL6HzA"
+    "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\n6z8RJm0+"
+    "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
+    "5nZ68ECQQDvYuI3\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY"
+    "Ap6LI9W\nIqv4vr6y38N79TTC\n-----END PRIVATE KEY-----\n\", ";
+static const char test_json_key_str_part3[] =
+    "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+    "\"client_email\": "
+    "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+    "com\", \"client_id\": "
+    "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+    "com\", \"type\": \"service_account\" }";
+
+static const char valid_oauth2_json_response[] =
+    "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
+    " \"expires_in\":3599, "
+    " \"token_type\":\"Bearer\"}";
+
+static const char test_user_data[] = "user data";
+
+static const char test_scope[] = "perm1 perm2";
+
+static const char test_signed_jwt[] = "signed jwt";
+
+static const char expected_service_account_http_body_prefix[] =
+    "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&"
+    "assertion=";
+
+static char *test_json_key_str(void) {
+  size_t result_len = strlen(test_json_key_str_part1) +
+                      strlen(test_json_key_str_part2) +
+                      strlen(test_json_key_str_part3);
+  char *result = gpr_malloc(result_len + 1);
+  char *current = result;
+  strcpy(result, test_json_key_str_part1);
+  current += strlen(test_json_key_str_part1);
+  strcpy(current, test_json_key_str_part2);
+  current += strlen(test_json_key_str_part2);
+  strcpy(current, test_json_key_str_part3);
+  return result;
+}
+
 typedef struct {
   const char *key;
   const char *value;
 } expected_md;
 
-static grpc_httpcli_response http_response(int status, char *body) {
+static grpc_httpcli_response http_response(int status, const char *body) {
   grpc_httpcli_response response;
   memset(&response, 0, sizeof(grpc_httpcli_response));
   response.status = status;
-  response.body = body;
+  response.body = (char *)body;
   response.body_length = strlen(body);
   return response;
 }
 
-static void test_compute_engine_creds_parsing_ok(void) {
+static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
-      http_response(200,
-                    "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
-                    " \"expires_in\":3599, "
-                    " \"token_type\":\"Bearer\"}");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+      http_response(200, valid_oauth2_json_response);
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_OK);
   GPR_ASSERT(token_lifetime.tv_sec == 3599);
@@ -81,33 +141,30 @@
   grpc_mdctx_orphan(ctx);
 }
 
-static void test_compute_engine_creds_parsing_bad_http_status(void) {
+static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response =
-      http_response(401,
-                    "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
-                    " \"expires_in\":3599, "
-                    " \"token_type\":\"Bearer\"}");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+      http_response(401, valid_oauth2_json_response);
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_mdctx_orphan(ctx);
 }
 
-static void test_compute_engine_creds_parsing_empty_http_body(void) {
+static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
   grpc_httpcli_response response = http_response(200, "");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_mdctx_orphan(ctx);
 }
 
-static void test_compute_engine_creds_parsing_invalid_json(void) {
+static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
@@ -116,13 +173,13 @@
                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
                     " \"expires_in\":3599, "
                     " \"token_type\":\"Bearer\"");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_mdctx_orphan(ctx);
 }
 
-static void test_compute_engine_creds_parsing_missing_token(void) {
+static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
@@ -130,13 +187,13 @@
                                                  "{"
                                                  " \"expires_in\":3599, "
                                                  " \"token_type\":\"Bearer\"}");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_mdctx_orphan(ctx);
 }
 
-static void test_compute_engine_creds_parsing_missing_token_type(void) {
+static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
@@ -145,13 +202,14 @@
                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
                     " \"expires_in\":3599, "
                     "}");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_mdctx_orphan(ctx);
 }
 
-static void test_compute_engine_creds_parsing_missing_token_lifetime(void) {
+static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
+    void) {
   grpc_mdctx *ctx = grpc_mdctx_create();
   grpc_mdelem *token_elem = NULL;
   gpr_timespec token_lifetime;
@@ -159,7 +217,7 @@
       http_response(200,
                     "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
                     " \"token_type\":\"Bearer\"}");
-  GPR_ASSERT(grpc_compute_engine_credentials_parse_server_response(
+  GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
   grpc_mdctx_orphan(ctx);
@@ -285,17 +343,285 @@
                                         composite_creds);
 }
 
+static void on_oauth2_creds_get_metadata_success(
+    void *user_data, grpc_mdelem **md_elems, size_t num_md,
+    grpc_credentials_status status) {
+  GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
+  GPR_ASSERT(num_md == 1);
+  GPR_ASSERT(
+      !strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization"));
+  GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
+                     "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
+  GPR_ASSERT(user_data != NULL);
+  GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+}
+
+static void on_oauth2_creds_get_metadata_failure(
+    void *user_data, grpc_mdelem **md_elems, size_t num_md,
+    grpc_credentials_status status) {
+  GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
+  GPR_ASSERT(num_md == 0);
+  GPR_ASSERT(user_data != NULL);
+  GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+}
+
+static void validate_compute_engine_http_request(
+    const grpc_httpcli_request *request) {
+  GPR_ASSERT(!request->use_ssl);
+  GPR_ASSERT(!strcmp(request->host, "metadata"));
+  GPR_ASSERT(
+      !strcmp(request->path,
+              "/computeMetadata/v1/instance/service-accounts/default/token"));
+  GPR_ASSERT(request->hdr_count == 1);
+  GPR_ASSERT(!strcmp(request->hdrs[0].key, "Metadata-Flavor"));
+  GPR_ASSERT(!strcmp(request->hdrs[0].value, "Google"));
+}
+
+static int compute_engine_httpcli_get_success_override(
+    const grpc_httpcli_request *request, gpr_timespec deadline,
+    grpc_httpcli_response_cb on_response, void *user_data) {
+  grpc_httpcli_response response =
+      http_response(200, valid_oauth2_json_response);
+  validate_compute_engine_http_request(request);
+  on_response(user_data, &response);
+  return 1;
+}
+
+static int compute_engine_httpcli_get_failure_override(
+    const grpc_httpcli_request *request, gpr_timespec deadline,
+    grpc_httpcli_response_cb on_response, void *user_data) {
+  grpc_httpcli_response response = http_response(403, "Not Authorized.");
+  validate_compute_engine_http_request(request);
+  on_response(user_data, &response);
+  return 1;
+}
+
+static int httpcli_post_should_not_be_called(
+    const grpc_httpcli_request *request, const char *body_bytes,
+    size_t body_size, gpr_timespec deadline,
+    grpc_httpcli_response_cb on_response, void *user_data) {
+  GPR_ASSERT("HTTP POST should not be called" == NULL);
+  return 1;
+}
+
+static int httpcli_get_should_not_be_called(
+    const grpc_httpcli_request *request, gpr_timespec deadline,
+    grpc_httpcli_response_cb on_response, void *user_data) {
+  GPR_ASSERT("HTTP GET should not be called" == NULL);
+  return 1;
+}
+
+static void test_compute_engine_creds_success(void) {
+  grpc_credentials *compute_engine_creds =
+      grpc_compute_engine_credentials_create();
+  GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
+  GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
+
+  /* First request: http get should be called. */
+  grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
+                            httpcli_post_should_not_be_called);
+  grpc_credentials_get_request_metadata(compute_engine_creds,
+                                        on_oauth2_creds_get_metadata_success,
+                                        (void *)test_user_data);
+
+  /* Second request: the cached token should be served directly. */
+  grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+                            httpcli_post_should_not_be_called);
+  grpc_credentials_get_request_metadata(compute_engine_creds,
+                                        on_oauth2_creds_get_metadata_success,
+                                        (void *)test_user_data);
+
+  grpc_credentials_unref(compute_engine_creds);
+  grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_compute_engine_creds_failure(void) {
+  grpc_credentials *compute_engine_creds =
+      grpc_compute_engine_credentials_create();
+  grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
+                            httpcli_post_should_not_be_called);
+  GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
+  GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
+  grpc_credentials_get_request_metadata(compute_engine_creds,
+                                        on_oauth2_creds_get_metadata_failure,
+                                        (void *)test_user_data);
+  grpc_credentials_unref(compute_engine_creds);
+  grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void validate_jwt_encode_and_sign_params(
+    const grpc_auth_json_key *json_key, const char *scope,
+    gpr_timespec token_lifetime) {
+  GPR_ASSERT(grpc_auth_json_key_is_valid(json_key));
+  GPR_ASSERT(json_key->private_key != NULL);
+  GPR_ASSERT(RSA_check_key(json_key->private_key));
+  GPR_ASSERT(json_key->type != NULL &&
+             !(strcmp(json_key->type, "service_account")));
+  GPR_ASSERT(json_key->private_key_id != NULL &&
+             !strcmp(json_key->private_key_id,
+                     "e6b5137873db8d2ef81e06a47289e6434ec8a165"));
+  GPR_ASSERT(json_key->client_id != NULL &&
+             !strcmp(json_key->client_id,
+                     "777-abaslkan11hlb6nmim3bpspl31ud.apps."
+                     "googleusercontent.com"));
+  GPR_ASSERT(json_key->client_email != NULL &&
+             !strcmp(json_key->client_email,
+                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
+                     "gserviceaccount.com"));
+  GPR_ASSERT(!strcmp(scope, test_scope));
+  GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime));
+}
+
+static char *encode_and_sign_jwt_success(const grpc_auth_json_key *json_key,
+                                         const char *scope,
+                                         gpr_timespec token_lifetime) {
+  validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
+  return gpr_strdup(test_signed_jwt);
+}
+
+static char *encode_and_sign_jwt_failure(const grpc_auth_json_key *json_key,
+                                         const char *scope,
+                                         gpr_timespec token_lifetime) {
+  validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
+  return NULL;
+}
+
+static char *encode_and_sign_jwt_should_not_be_called(
+    const grpc_auth_json_key *json_key, const char *scope,
+    gpr_timespec token_lifetime) {
+  GPR_ASSERT("grpc_jwt_encode_and_sign should not be called" == NULL);
+}
+
+static void validate_service_account_http_request(
+    const grpc_httpcli_request *request, const char *body, size_t body_size) {
+  /* The content of the assertion is tested extensively in json_token_test. */
+  char *expected_body = NULL;
+  GPR_ASSERT(body != NULL);
+  GPR_ASSERT(body_size != 0);
+  expected_body = gpr_malloc(strlen(expected_service_account_http_body_prefix) +
+                             strlen(test_signed_jwt) + 1);
+  sprintf(expected_body, "%s%s", expected_service_account_http_body_prefix,
+          test_signed_jwt);
+  GPR_ASSERT(strlen(expected_body) == body_size);
+  GPR_ASSERT(!memcmp(expected_body, body, body_size));
+  gpr_free(expected_body);
+  GPR_ASSERT(request->use_ssl);
+  GPR_ASSERT(!strcmp(request->host, "www.googleapis.com"));
+  GPR_ASSERT(!strcmp(request->path, "/oauth2/v3/token"));
+  GPR_ASSERT(request->hdr_count == 1);
+  GPR_ASSERT(!strcmp(request->hdrs[0].key, "Content-Type"));
+  GPR_ASSERT(
+      !strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded"));
+}
+
+static int service_account_httpcli_post_success(
+    const grpc_httpcli_request *request, const char *body, size_t body_size,
+    gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+    void *user_data) {
+  grpc_httpcli_response response =
+      http_response(200, valid_oauth2_json_response);
+  validate_service_account_http_request(request, body, body_size);
+  on_response(user_data, &response);
+  return 1;
+}
+
+static int service_account_httpcli_post_failure(
+    const grpc_httpcli_request *request, const char *body, size_t body_size,
+    gpr_timespec deadline, grpc_httpcli_response_cb on_response,
+    void *user_data) {
+  grpc_httpcli_response response = http_response(403, "Not Authorized.");
+  validate_service_account_http_request(request, body, body_size);
+  on_response(user_data, &response);
+  return 1;
+}
+
+static void test_service_accounts_creds_success(void) {
+  char *json_key_string = test_json_key_str();
+  grpc_credentials *service_account_creds =
+      grpc_service_account_credentials_create(json_key_string, test_scope,
+                                              grpc_max_auth_token_lifetime);
+  GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
+  GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
+
+  /* First request: http get should be called. */
+  grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
+  grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+                            service_account_httpcli_post_success);
+  grpc_credentials_get_request_metadata(service_account_creds,
+                                        on_oauth2_creds_get_metadata_success,
+                                        (void *)test_user_data);
+
+  /* Second request: the cached token should be served directly. */
+  grpc_jwt_encode_and_sign_set_override(
+      encode_and_sign_jwt_should_not_be_called);
+  grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+                            httpcli_post_should_not_be_called);
+  grpc_credentials_get_request_metadata(service_account_creds,
+                                        on_oauth2_creds_get_metadata_success,
+                                        (void *)test_user_data);
+
+  gpr_free(json_key_string);
+  grpc_credentials_unref(service_account_creds);
+  grpc_jwt_encode_and_sign_set_override(NULL);
+  grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_service_accounts_creds_http_failure(void) {
+  char *json_key_string = test_json_key_str();
+  grpc_credentials *service_account_creds =
+      grpc_service_account_credentials_create(json_key_string, test_scope,
+                                              grpc_max_auth_token_lifetime);
+  GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
+  GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
+
+  grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
+  grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+                            service_account_httpcli_post_failure);
+  grpc_credentials_get_request_metadata(service_account_creds,
+                                        on_oauth2_creds_get_metadata_failure,
+                                        (void *)test_user_data);
+
+  gpr_free(json_key_string);
+  grpc_credentials_unref(service_account_creds);
+  grpc_httpcli_set_override(NULL, NULL);
+}
+
+static void test_service_accounts_creds_signing_failure(void) {
+  char *json_key_string = test_json_key_str();
+  grpc_credentials *service_account_creds =
+      grpc_service_account_credentials_create(json_key_string, test_scope,
+                                              grpc_max_auth_token_lifetime);
+  GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
+  GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
+
+  grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
+  grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+                            httpcli_post_should_not_be_called);
+  grpc_credentials_get_request_metadata(service_account_creds,
+                                        on_oauth2_creds_get_metadata_failure,
+                                        (void *)test_user_data);
+
+  gpr_free(json_key_string);
+  grpc_credentials_unref(service_account_creds);
+  grpc_httpcli_set_override(NULL, NULL);
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
-  test_compute_engine_creds_parsing_ok();
-  test_compute_engine_creds_parsing_bad_http_status();
-  test_compute_engine_creds_parsing_empty_http_body();
-  test_compute_engine_creds_parsing_invalid_json();
-  test_compute_engine_creds_parsing_missing_token();
-  test_compute_engine_creds_parsing_missing_token_type();
-  test_compute_engine_creds_parsing_missing_token_lifetime();
+  test_oauth2_token_fetcher_creds_parsing_ok();
+  test_oauth2_token_fetcher_creds_parsing_bad_http_status();
+  test_oauth2_token_fetcher_creds_parsing_empty_http_body();
+  test_oauth2_token_fetcher_creds_parsing_invalid_json();
+  test_oauth2_token_fetcher_creds_parsing_missing_token();
+  test_oauth2_token_fetcher_creds_parsing_missing_token_type();
+  test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime();
   test_iam_creds();
   test_ssl_oauth2_composite_creds();
   test_ssl_oauth2_iam_composite_creds();
+  test_compute_engine_creds_success();
+  test_compute_engine_creds_failure();
+  test_service_accounts_creds_success();
+  test_service_accounts_creds_http_failure();
+  test_service_accounts_creds_signing_failure();
   return 0;
 }
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
new file mode 100644
index 0000000..c5cc3ad
--- /dev/null
+++ b/test/core/security/fetch_oauth2.c
@@ -0,0 +1,177 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "src/core/security/credentials.h"
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/cmdline.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/sync.h>
+
+typedef struct {
+  gpr_cv cv;
+  gpr_mu mu;
+  int is_done;
+} synchronizer;
+
+static void on_oauth2_response(void *user_data, grpc_mdelem **md_elems,
+                               size_t num_md, grpc_credentials_status status) {
+  synchronizer *sync = user_data;
+  char *token;
+  gpr_slice token_slice;
+  if (status == GRPC_CREDENTIALS_ERROR) {
+    gpr_log(GPR_ERROR, "Fetching token failed.");
+  } else {
+    GPR_ASSERT(num_md == 1);
+    token_slice = md_elems[0]->value->slice;
+    token = gpr_malloc(GPR_SLICE_LENGTH(token_slice) + 1);
+    memcpy(token, GPR_SLICE_START_PTR(token_slice),
+           GPR_SLICE_LENGTH(token_slice));
+    token[GPR_SLICE_LENGTH(token_slice)] = '\0';
+    printf("Got token: %s.\n", token);
+    gpr_free(token);
+  }
+  gpr_mu_lock(&sync->mu);
+  sync->is_done = 1;
+  gpr_mu_unlock(&sync->mu);
+  gpr_cv_signal(&sync->cv);
+}
+
+static grpc_credentials *create_service_account_creds(
+    const char *json_key_file_path, const char *scope) {
+  char json_key[8192]; /* Should be plenty. */
+  char *current = json_key;
+  FILE *json_key_file = fopen(json_key_file_path, "r");
+  if (json_key_file == NULL) {
+    gpr_log(GPR_ERROR, "Invalid path for json key file: %s.",
+            json_key_file_path);
+    exit(1);
+  }
+
+  do {
+    size_t bytes_read = fread(
+        current, 1, sizeof(json_key) - (current - json_key), json_key_file);
+    if (bytes_read == 0) {
+      if (!feof(json_key_file)) {
+        gpr_log(GPR_ERROR, "Error occured while reading %s.",
+                json_key_file_path);
+        exit(1);
+      }
+      break;
+    }
+    current += bytes_read;
+  } while (sizeof(json_key) > (current - json_key));
+
+  if ((current - json_key) == sizeof(json_key)) {
+    gpr_log(GPR_ERROR, "Json key file %s exceeds size limit (%d bytes).",
+            json_key_file_path, (int)sizeof(json_key));
+    exit(1);
+  }
+  fclose(json_key_file);
+
+  return grpc_service_account_credentials_create(json_key, scope,
+                                                 grpc_max_auth_token_lifetime);
+}
+
+int main(int argc, char **argv) {
+  synchronizer sync;
+  grpc_credentials *creds = NULL;
+  char *json_key_file_path = NULL;
+  int use_gce = 0;
+  char *scope = NULL;
+  gpr_cmdline *cl = gpr_cmdline_create("fetch_oauth2");
+  gpr_cmdline_add_string(cl, "json_key", "File path of the json key.",
+                         &json_key_file_path);
+  gpr_cmdline_add_string(cl, "scope", "Space delimited permissions.", &scope);
+  gpr_cmdline_add_flag(
+      cl, "gce",
+      "Get a token from the GCE metadata server (only works in GCE).",
+      &use_gce);
+  gpr_cmdline_parse(cl, argc, argv);
+
+  grpc_init();
+
+  if (use_gce) {
+    if (json_key_file_path != NULL || scope != NULL) {
+      gpr_log(GPR_INFO,
+              "Ignoring json key and scope to get a token from the GCE "
+              "metadata server.");
+    }
+    creds = grpc_compute_engine_credentials_create();
+    if (creds == NULL) {
+      gpr_log(GPR_ERROR, "Could not create gce credentials.");
+      exit(1);
+    }
+  } else {
+    if (json_key_file_path == NULL) {
+      gpr_log(GPR_ERROR, "missing --json_key option.");
+      exit(1);
+    }
+    if (scope == NULL) {
+      gpr_log(GPR_ERROR, "Missing --scope option.");
+      exit(1);
+    }
+
+    creds = create_service_account_creds(json_key_file_path, scope);
+    if (creds == NULL) {
+      gpr_log(GPR_ERROR,
+              "Could not create service account creds. %s does probably not "
+              "contain a valid json key.",
+              json_key_file_path);
+      exit(1);
+    }
+  }
+  GPR_ASSERT(creds != NULL);
+
+  gpr_mu_init(&sync.mu);
+  gpr_cv_init(&sync.cv);
+  sync.is_done = 0;
+
+  grpc_credentials_get_request_metadata(creds, on_oauth2_response, &sync);
+
+  gpr_mu_lock(&sync.mu);
+  while (!sync.is_done) gpr_cv_wait(&sync.cv, &sync.mu, gpr_inf_future);
+  gpr_mu_unlock(&sync.mu);
+
+  gpr_mu_destroy(&sync.mu);
+  gpr_cv_destroy(&sync.cv);
+  grpc_credentials_release(creds);
+  gpr_cmdline_destroy(cl);
+  grpc_shutdown();
+  return 0;
+}