diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index 32b6a8d8e4a0537db5b62583e6040c4b4cbece36..a0bb92848b877f095d07d3ad714fc373972b7ffa 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -32,24 +32,20 @@
  */
 
 #include <cctype>
-#include <string>
 #include <map>
 #include <vector>
 
+#include "src/compiler/config.h"
 #include "src/compiler/ruby_generator.h"
 #include "src/compiler/ruby_generator_helpers-inl.h"
 #include "src/compiler/ruby_generator_map-inl.h"
 #include "src/compiler/ruby_generator_string-inl.h"
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
-
-using google::protobuf::FileDescriptor;
-using google::protobuf::ServiceDescriptor;
-using google::protobuf::MethodDescriptor;
-using google::protobuf::io::Printer;
-using google::protobuf::io::StringOutputStream;
+
+using grpc::protobuf::FileDescriptor;
+using grpc::protobuf::ServiceDescriptor;
+using grpc::protobuf::MethodDescriptor;
+using grpc::protobuf::io::Printer;
+using grpc::protobuf::io::StringOutputStream;
 using std::map;
 using std::vector;
 
@@ -57,38 +53,38 @@ namespace grpc_ruby_generator {
 namespace {
 
 // Prints out the method using the ruby gRPC DSL.
-void PrintMethod(const MethodDescriptor *method, const std::string &package,
+void PrintMethod(const MethodDescriptor *method, const grpc::string &package,
                  Printer *out) {
-  std::string input_type = RubyTypeOf(method->input_type()->name(), package);
+  grpc::string input_type = RubyTypeOf(method->input_type()->name(), package);
   if (method->client_streaming()) {
     input_type = "stream(" + input_type + ")";
   }
-  std::string output_type = RubyTypeOf(method->output_type()->name(), package);
+  grpc::string output_type = RubyTypeOf(method->output_type()->name(), package);
   if (method->server_streaming()) {
     output_type = "stream(" + output_type + ")";
   }
-  std::map<std::string, std::string> method_vars =
+  std::map<grpc::string, grpc::string> method_vars =
       ListToDict({"mth.name", method->name(), "input.type", input_type,
                   "output.type", output_type, });
   out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n");
 }
 
 // Prints out the service using the ruby gRPC DSL.
-void PrintService(const ServiceDescriptor *service, const std::string &package,
+void PrintService(const ServiceDescriptor *service, const grpc::string &package,
                   Printer *out) {
   if (service->method_count() == 0) {
     return;
   }
 
   // Begin the service module
-  std::map<std::string, std::string> module_vars =
+  std::map<grpc::string, grpc::string> module_vars =
       ListToDict({"module.name", CapitalizeFirst(service->name()), });
   out->Print(module_vars, "module $module.name$\n");
   out->Indent();
 
   // TODO(temiola): add documentation
-  std::string doc = "TODO: add proto service documentation here";
-  std::map<std::string, std::string> template_vars =
+  grpc::string doc = "TODO: add proto service documentation here";
+  std::map<grpc::string, grpc::string> template_vars =
       ListToDict({"Documentation", doc, });
   out->Print("\n");
   out->Print(template_vars, "# $Documentation$\n");
@@ -101,7 +97,7 @@ void PrintService(const ServiceDescriptor *service, const std::string &package,
   out->Print("\n");
   out->Print("self.marshal_class_method = :encode\n");
   out->Print("self.unmarshal_class_method = :decode\n");
-  std::map<std::string, std::string> pkg_vars =
+  std::map<grpc::string, grpc::string> pkg_vars =
       ListToDict({"service.name", service->name(), "pkg.name", package, });
   out->Print(pkg_vars, "self.service_name = '$pkg.name$.$service.name$'\n");
   out->Print("\n");
@@ -121,8 +117,8 @@ void PrintService(const ServiceDescriptor *service, const std::string &package,
 
 }  // namespace
 
-std::string GetServices(const FileDescriptor *file) {
-  std::string output;
+grpc::string GetServices(const FileDescriptor *file) {
+  grpc::string output;
   StringOutputStream output_stream(&output);
   Printer out(&output_stream, '$');
 
@@ -133,7 +129,7 @@ std::string GetServices(const FileDescriptor *file) {
   }
 
   // Write out a file header.
-  std::map<std::string, std::string> header_comment_vars = ListToDict(
+  std::map<grpc::string, grpc::string> header_comment_vars = ListToDict(
       {"file.name", file->name(), "file.package", file->package(), });
   out.Print("# Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
   out.Print(header_comment_vars,
@@ -144,15 +140,15 @@ std::string GetServices(const FileDescriptor *file) {
   // Write out require statemment to import the separately generated file
   // that defines the messages used by the service. This is generated by the
   // main ruby plugin.
-  std::map<std::string, std::string> dep_vars =
+  std::map<grpc::string, grpc::string> dep_vars =
       ListToDict({"dep.name", MessagesRequireName(file), });
   out.Print(dep_vars, "require '$dep.name$'\n");
 
   // Write out services within the modules
   out.Print("\n");
-  std::vector<std::string> modules = Split(file->package(), '.');
+  std::vector<grpc::string> modules = Split(file->package(), '.');
   for (size_t i = 0; i < modules.size(); ++i) {
-    std::map<std::string, std::string> module_vars =
+    std::map<grpc::string, grpc::string> module_vars =
         ListToDict({"module.name", CapitalizeFirst(modules[i]), });
     out.Print(module_vars, "module $module.name$\n");
     out.Indent();
diff --git a/src/compiler/ruby_generator.h b/src/compiler/ruby_generator.h
index 4dd38e0c274a1d8d44786764ce9f3a65b5edddd4..a2ab36d4d99dad5b9b1976b1568b1c31810b9a1f 100644
--- a/src/compiler/ruby_generator.h
+++ b/src/compiler/ruby_generator.h
@@ -34,17 +34,11 @@
 #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
 #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
 
-#include <string>
-
-namespace google {
-namespace protobuf {
-class FileDescriptor;
-}  // namespace protobuf
-}  // namespace google
+#include "src/compiler/config.h"
 
 namespace grpc_ruby_generator {
 
-std::string GetServices(const google::protobuf::FileDescriptor *file);
+grpc::string GetServices(const grpc::protobuf::FileDescriptor *file);
 
 }  // namespace grpc_ruby_generator
 
diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h
index f3a087b3f8efa7668e49a9203f538d0762ce251e..9da7cab3c7f3dd5d33b023f67fc26a50cbd8686d 100644
--- a/src/compiler/ruby_generator_helpers-inl.h
+++ b/src/compiler/ruby_generator_helpers-inl.h
@@ -34,15 +34,13 @@
 #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
 #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
 
-#include <string>
-
-#include <google/protobuf/descriptor.h>
+#include "src/compiler/config.h"
 #include "src/compiler/ruby_generator_string-inl.h"
 
 namespace grpc_ruby_generator {
 
-inline bool ServicesFilename(const google::protobuf::FileDescriptor *file,
-                             std::string *file_name_or_error) {
+inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file,
+                             grpc::string *file_name_or_error) {
   // Get output file name.
   static const unsigned proto_suffix_length = 6;  // length of ".proto"
   if (file->name().size() > proto_suffix_length &&
@@ -57,8 +55,8 @@ inline bool ServicesFilename(const google::protobuf::FileDescriptor *file,
   }
 }
 
-inline std::string MessagesRequireName(
-    const google::protobuf::FileDescriptor *file) {
+inline grpc::string MessagesRequireName(
+    const grpc::protobuf::FileDescriptor *file) {
   return Replace(file->name(), ".proto", "");
 }
 
diff --git a/src/compiler/ruby_generator_map-inl.h b/src/compiler/ruby_generator_map-inl.h
index f902b6d98f80b12345eb9a3987ecd74f53d2982d..6b87774f2136b576a47fdd822b4d1dc9163359f2 100644
--- a/src/compiler/ruby_generator_map-inl.h
+++ b/src/compiler/ruby_generator_map-inl.h
@@ -34,11 +34,12 @@
 #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
 #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
 
+#include "src/compiler/config.h"
+
 #include <iostream>
 #include <initializer_list>
 #include <map>
 #include <ostream>  // NOLINT
-#include <string>
 #include <vector>
 
 using std::initializer_list;
@@ -49,18 +50,18 @@ namespace grpc_ruby_generator {
 
 // Converts an initializer list of the form { key0, value0, key1, value1, ... }
 // into a map of key* to value*. Is merely a readability helper for later code.
-inline std::map<std::string, std::string> ListToDict(
-    const initializer_list<std::string> &values) {
+inline std::map<grpc::string, grpc::string> ListToDict(
+    const initializer_list<grpc::string> &values) {
   if (values.size() % 2 != 0) {
     std::cerr << "Not every 'key' has a value in `values`."
               << std::endl;
   }
-  std::map<std::string, std::string> value_map;
+  std::map<grpc::string, grpc::string> value_map;
   auto value_iter = values.begin();
   for (unsigned i = 0; i < values.size() / 2; ++i) {
-    std::string key = *value_iter;
+    grpc::string key = *value_iter;
     ++value_iter;
-    std::string value = *value_iter;
+    grpc::string value = *value_iter;
     value_map[key] = value;
     ++value_iter;
   }
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index bdd314c16e5c809e8f43f8c22a6ca7948605f4b0..8da3a88da2937d1cb6d33956be378d927715f0bd 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -34,8 +34,9 @@
 #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
 #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
 
+#include "src/compiler/config.h"
+
 #include <algorithm>
-#include <string>
 #include <sstream>
 #include <vector>
 
@@ -45,10 +46,10 @@ using std::transform;
 namespace grpc_ruby_generator {
 
 // Split splits a string using char into elems.
-inline std::vector<std::string> &Split(const std::string &s, char delim,
-                                       std::vector<std::string> *elems) {
+inline std::vector<grpc::string> &Split(const grpc::string &s, char delim,
+                                        std::vector<grpc::string> *elems) {
   std::stringstream ss(s);
-  std::string item;
+  grpc::string item;
   while (getline(ss, item, delim)) {
     elems->push_back(item);
   }
@@ -56,17 +57,17 @@ inline std::vector<std::string> &Split(const std::string &s, char delim,
 }
 
 // Split splits a string using char, returning the result in a vector.
-inline std::vector<std::string> Split(const std::string &s, char delim) {
-  std::vector<std::string> elems;
+inline std::vector<grpc::string> Split(const grpc::string &s, char delim) {
+  std::vector<grpc::string> elems;
   Split(s, delim, &elems);
   return elems;
 }
 
 // Replace replaces from with to in s.
-inline std::string Replace(std::string s, const std::string &from,
-                           const std::string &to) {
+inline grpc::string Replace(grpc::string s, const grpc::string &from,
+                            const grpc::string &to) {
   size_t start_pos = s.find(from);
-  if (start_pos == std::string::npos) {
+  if (start_pos == grpc::string::npos) {
     return s;
   }
   s.replace(start_pos, from.length(), to);
@@ -74,10 +75,10 @@ inline std::string Replace(std::string s, const std::string &from,
 }
 
 // ReplaceAll replaces all instances of search with replace in s.
-inline std::string ReplaceAll(std::string s, const std::string &search,
-                              const std::string &replace) {
+inline grpc::string ReplaceAll(grpc::string s, const grpc::string &search,
+                               const grpc::string &replace) {
   size_t pos = 0;
-  while ((pos = s.find(search, pos)) != std::string::npos) {
+  while ((pos = s.find(search, pos)) != grpc::string::npos) {
     s.replace(pos, search.length(), replace);
     pos += replace.length();
   }
@@ -85,10 +86,10 @@ inline std::string ReplaceAll(std::string s, const std::string &search,
 }
 
 // ReplacePrefix replaces from with to in s if search is a prefix of s.
-inline bool ReplacePrefix(std::string *s, const std::string &from,
-                          const std::string &to) {
+inline bool ReplacePrefix(grpc::string *s, const grpc::string &from,
+                          const grpc::string &to) {
   size_t start_pos = s->find(from);
-  if (start_pos == std::string::npos || start_pos != 0) {
+  if (start_pos == grpc::string::npos || start_pos != 0) {
     return false;
   }
   s->replace(start_pos, from.length(), to);
@@ -96,7 +97,7 @@ inline bool ReplacePrefix(std::string *s, const std::string &from,
 }
 
 // CapitalizeFirst capitalizes the first char in a string.
-inline std::string CapitalizeFirst(std::string s) {
+inline grpc::string CapitalizeFirst(grpc::string s) {
   if (s.empty()) {
     return s;
   }
@@ -105,15 +106,15 @@ inline std::string CapitalizeFirst(std::string s) {
 }
 
 // RubyTypeOf updates a proto type to the required ruby equivalent.
-inline std::string RubyTypeOf(const std::string &a_type,
-                              const std::string &package) {
-  std::string res(a_type);
+inline grpc::string RubyTypeOf(const grpc::string &a_type,
+                               const grpc::string &package) {
+  grpc::string res(a_type);
   ReplacePrefix(&res, package, "");  // remove the leading package if present
   ReplacePrefix(&res, ".", "");      // remove the leading . (no package)
-  if (res.find('.') == std::string::npos) {
+  if (res.find('.') == grpc::string::npos) {
     return res;
   } else {
-    std::vector<std::string> prefixes_and_type = Split(res, '.');
+    std::vector<grpc::string> prefixes_and_type = Split(res, '.');
     for (unsigned int i = 0; i < prefixes_and_type.size(); ++i) {
       if (i != 0) {
         res += "::";  // switch '.' to the ruby module delim
diff --git a/src/compiler/ruby_plugin.cc b/src/compiler/ruby_plugin.cc
index 4a6e9f7a5d38c1d82962ba3ca5a8b5b2995c292a..bd10d46e9ca774a6aab57e63a112e1293d2eed35 100644
--- a/src/compiler/ruby_plugin.cc
+++ b/src/compiler/ruby_plugin.cc
@@ -32,43 +32,35 @@
  */
 
 // Generates Ruby gRPC service interface out of Protobuf IDL.
-//
-// This is a Proto2 compiler plugin.  See net/proto2/compiler/proto/plugin.proto
-// and net/proto2/compiler/public/plugin.h for more information on plugins.
 
 #include <memory>
-#include <string>
 
+#include "src/compiler/config.h"
 #include "src/compiler/ruby_generator.h"
 #include "src/compiler/ruby_generator_helpers-inl.h"
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/compiler/plugin.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/descriptor.h>
 
-class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
+class RubyGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
  public:
   RubyGrpcGenerator() {}
   ~RubyGrpcGenerator() {}
 
-  bool Generate(const google::protobuf::FileDescriptor *file,
-                const std::string &parameter,
-                google::protobuf::compiler::GeneratorContext *context,
-                std::string *error) const {
-    std::string code = grpc_ruby_generator::GetServices(file);
+  bool Generate(const grpc::protobuf::FileDescriptor *file,
+                const grpc::string &parameter,
+                grpc::protobuf::compiler::GeneratorContext *context,
+                grpc::string *error) const {
+    grpc::string code = grpc_ruby_generator::GetServices(file);
     if (code.size() == 0) {
       return true;  // don't generate a file if there are no services
     }
 
     // Get output file name.
-    std::string file_name;
+    grpc::string file_name;
     if (!grpc_ruby_generator::ServicesFilename(file, &file_name)) {
       return false;
     }
-    std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
+    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
         context->Open(file_name));
-    google::protobuf::io::CodedOutputStream coded_out(output.get());
+    grpc::protobuf::io::CodedOutputStream coded_out(output.get());
     coded_out.WriteRaw(code.data(), code.size());
     return true;
   }
@@ -76,5 +68,5 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
 
 int main(int argc, char *argv[]) {
   RubyGrpcGenerator generator;
-  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+  return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
 }
diff --git a/src/ruby/Rakefile b/src/ruby/Rakefile
index b27305d16c3abfa766e26ab2bcb8f942bc76ef0c..afb354e922826738a9401bd606d9cccad2b6c960 100755
--- a/src/ruby/Rakefile
+++ b/src/ruby/Rakefile
@@ -2,14 +2,17 @@
 require 'rake/extensiontask'
 require 'rspec/core/rake_task'
 require 'rubocop/rake_task'
+require 'bundler/gem_tasks'
 
-desc 'Run Rubocop to check for style violations'
+# Add rubocop style checking tasks
 RuboCop::RakeTask.new
 
+# Add the extension compiler task
 Rake::ExtensionTask.new 'grpc' do |ext|
   ext.lib_dir = File.join('lib', 'grpc')
 end
 
+# Define the test suites
 SPEC_SUITES = [
   { id: :wrapper, title: 'wrapper layer', files: %w(spec/*.rb) },
   { id: :idiomatic, title: 'idiomatic layer', dir: %w(spec/generic),
@@ -19,36 +22,34 @@ SPEC_SUITES = [
   { id: :server, title: 'rpc server thread tests', dir: %w(spec/generic),
     tag: 'server' }
 ]
+namespace :suite do
+  SPEC_SUITES.each do |suite|
+    desc "Run all specs in the #{suite[:title]} spec suite"
+    RSpec::Core::RakeTask.new(suite[:id]) do |t|
+      spec_files = []
+      suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
+
+      if suite[:dir]
+        suite[:dir].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
+      end
+      helper = 'spec/spec_helper.rb'
+      spec_files << helper unless spec_files.include?(helper)
 
-desc 'Run all RSpec tests'
-namespace :spec do
-  namespace :suite do
-    SPEC_SUITES.each do |suite|
-      desc "Run all specs in #{suite[:title]} spec suite"
-      RSpec::Core::RakeTask.new(suite[:id]) do |t|
-        spec_files = []
-        suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
-
-        if suite[:dirs]
-          suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
-        end
-
-        t.pattern = spec_files
-        t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
-        if suite[:tags]
-          t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
-        end
+      t.pattern = spec_files
+      t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
+      if suite[:tags]
+        t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
       end
     end
   end
 end
 
-desc 'Compiles the extension then runs all the tests'
-task :all
+# Define dependencies between the suites.
+task 'suite:wrapper' => [:compile, :rubocop]
+task 'suite:idiomatic' => 'suite:wrapper'
+task 'suite:bidi' => 'suite:wrapper'
+task 'suite:server' => 'suite:wrapper'
 
+desc 'Compiles the gRPC extension then runs all the tests'
+task all: ['suite:idiomatic', 'suite:bidi', 'suite:server']
 task default: :all
-task 'spec:suite:wrapper' => [:compile, :rubocop]
-task 'spec:suite:idiomatic' => 'spec:suite:wrapper'
-task 'spec:suite:bidi' => 'spec:suite:wrapper'
-task 'spec:suite:server' => 'spec:suite:wrapper'
-task all: ['spec:suite:idiomatic', 'spec:suite:bidi', 'spec:suite:server']
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 73f2d37e305bdef89aa4ea71fa0b21822369e5d9..0c98fc40d91a5949d2142c232d75e0151b4273c7 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -384,13 +384,7 @@ describe 'ClientStub' do
         th.join
       end
 
-      # disabled because an unresolved wire-protocol implementation feature
-      #
-      # - servers should be able initiate messaging, however, as it stand
-      # servers don't know if all the client metadata has been sent until
-      # they receive a message from the client.  Without receiving all the
-      # metadata, the server does not accept the call, so this test hangs.
-      xit 'supports a server-initiated ping pong', bidi: true do
+      it 'supports a server-initiated ping pong', bidi: true do
         server_port = create_test_server
         host = "localhost:#{server_port}"
         th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, false)