Merge pull request #11510 from ncteisen/testing-trickle-diff

Test PR for the New Trickle Diff
diff --git a/BUILD b/BUILD
index 04dba30..495bb66 100644
--- a/BUILD
+++ b/BUILD
@@ -930,8 +930,8 @@
     deps = [
         "grpc_base",
         "grpc_client_channel",
-        "grpc_secure",
         "grpc_resolver_fake",
+        "grpc_secure",
     ],
 )
 
@@ -1025,8 +1025,8 @@
     name = "grpc_resolver_fake",
     srcs = ["src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c"],
     hdrs = ["src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"],
-    visibility = ["//test:__subpackages__"],
     language = "c",
+    visibility = ["//test:__subpackages__"],
     deps = [
         "grpc_base",
         "grpc_client_channel",
diff --git a/binding.gyp b/binding.gyp
index d5bb27f..94555f0 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -115,6 +115,15 @@
         ]
       }, {
         'conditions': [
+          ["target_arch=='ia32'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
+          }],
+          ["target_arch=='x64'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
+          }],
+          ["target_arch=='arm'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
+          }],
           ['grpc_alpn=="true"', {
             'defines': [
               'TSI_OPENSSL_ALPN_SUPPORT=1'
@@ -127,17 +136,6 @@
         ],
         'include_dirs': [
           '<(node_root_dir)/deps/openssl/openssl/include',
-        ],
-        'conditions': [
-         ["target_arch=='ia32'", {
-             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
-         }],
-         ["target_arch=='x64'", {
-             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
-         }],
-         ["target_arch=='arm'", {
-             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
-         }]
         ]
       }],
       ['OS == "win"', {
diff --git a/config.w32 b/config.w32
index 919587d..5c82e34 100644
--- a/config.w32
+++ b/config.w32
@@ -640,4 +640,134 @@
     "/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+
     "/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+
     "/I"+configure_module_dirname+"\\third_party\\zlib");
+
+  base_dir = get_define('BUILD_DIR');
+  FSO.CreateFolder(base_dir+"\\ext");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\boringssl");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census\\gen");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\fake");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\deadline");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\client");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\message_compress");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\server");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\load_reporting");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\max_age");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\message_size");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\workarounds");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\alpn");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client\\insecure");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client\\secure");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server\\insecure");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server\\secure");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\transport");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\channel");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\compression");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\debug");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\context");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\composite");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\fake");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\google_default");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\iam");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\jwt");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\support");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\surface");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\transport");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\plugin_registry");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext\\grpc");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\aes");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\asn1");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\base64");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bio");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bn");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bn\\asm");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\buf");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bytestring");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\chacha");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\cipher");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\cmac");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\conf");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\curve25519");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\des");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\dh");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\digest");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\dsa");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ec");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ecdh");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ecdsa");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\engine");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\err");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\evp");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\hkdf");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\hmac");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\lhash");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\md4");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\md5");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\modes");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\newhope");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\obj");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pem");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pkcs8");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\poly1305");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rand");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rc4");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rsa");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\sha");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\stack");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\x509");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\x509v3");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\ssl");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\nanopb");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\zlib");
+  _build_dirs = new Array();
+  for (i = 0; i < build_dirs.length; i++) {
+    if (build_dirs[i].indexOf('grpc') == -1) {
+      _build_dirs[_build_dirs.length] = build_dirs[i];
+    }
+  }
+  build_dirs = _build_dirs;
+
 }
diff --git a/package.json b/package.json
index e050a34..451a777 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,7 @@
     "arguejs": "^0.2.3",
     "lodash": "^4.15.0",
     "nan": "^2.0.0",
-    "node-pre-gyp": "^0.6.0",
+    "node-pre-gyp": "^0.6.35",
     "protobufjs": "^5.0.0"
   },
   "devDependencies": {
diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h
index 6f6220c..9c9589e 100644
--- a/src/compiler/objective_c_generator_helpers.h
+++ b/src/compiler/objective_c_generator_helpers.h
@@ -23,6 +23,8 @@
 #include "src/compiler/config.h"
 #include "src/compiler/generator_helpers.h"
 
+#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
+
 namespace grpc_objective_c_generator {
 
 using ::grpc::protobuf::FileDescriptor;
@@ -30,7 +32,7 @@
 using ::grpc::string;
 
 inline string MessageHeaderName(const FileDescriptor *file) {
-  return grpc_generator::FileNameInUpperCamel(file) + ".pbobjc.h";
+  return google::protobuf::compiler::objectivec::FilePath(file) + ".pbobjc.h";
 }
 
 inline string ServiceClassName(const ServiceDescriptor *service) {
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index bd9bc74..96a3375 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -44,7 +44,8 @@
       return true;
     }
 
-    ::grpc::string file_name = grpc_generator::FileNameInUpperCamel(file);
+    ::grpc::string file_name =
+        google::protobuf::compiler::objectivec::FilePath(file);
     ::grpc::string prefix = file->options().objc_class_prefix();
 
     {
diff --git a/src/csharp/Grpc.Core.Tests/ServerTest.cs b/src/csharp/Grpc.Core.Tests/ServerTest.cs
index f6343f2..8844147 100644
--- a/src/csharp/Grpc.Core.Tests/ServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ServerTest.cs
@@ -17,6 +17,7 @@
 #endregion
 
 using System;
+using System.IO;
 using System.Linq;
 using Grpc.Core;
 using Grpc.Core.Internal;
@@ -66,6 +67,21 @@
         }
 
         [Test]
+        public void StartThrowsWithUnboundPorts()
+        {
+            int twiceBoundPort = 9999;
+            Server server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
+            {
+                Ports = {
+                    new ServerPort("localhost", twiceBoundPort, ServerCredentials.Insecure),
+                    new ServerPort("localhost", twiceBoundPort, ServerCredentials.Insecure)
+                }
+            };
+            Assert.Throws(typeof(IOException), () => server.Start());
+            server.ShutdownAsync().Wait();
+        }
+
+        [Test]
         public void CannotModifyAfterStarted()
         {
             Server server = new Server
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index 462713e..77ad876 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -19,6 +19,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using Grpc.Core.Internal;
@@ -140,6 +141,7 @@
 
         /// <summary>
         /// Starts the server.
+        /// Throws <c>IOException</c> if not successful.
         /// </summary>
         public void Start()
         {
@@ -148,7 +150,8 @@
                 GrpcPreconditions.CheckState(!startRequested);
                 GrpcPreconditions.CheckState(!shutdownRequested);
                 startRequested = true;
-                
+
+                CheckPortsBoundSuccessfully();
                 handle.Start();
 
                 for (int i = 0; i < requestCallTokensPerCq; i++)
@@ -301,6 +304,22 @@
             }
         }
 
+        /// <summary>
+        /// Checks that all ports have been bound successfully.
+        /// </summary>
+        private void CheckPortsBoundSuccessfully()
+        {
+            lock (myLock)
+            {
+                var unboundPort = ports.FirstOrDefault(port => port.BoundPort == 0);
+                if (unboundPort != null)
+                {
+                    throw new IOException(
+                        string.Format("Failed to bind port \"{0}:{1}\"", unboundPort.Host, unboundPort.Port));
+                }
+            }
+        }
+
         private void DisposeHandle()
         {
             var activeCallCount = activeCallCounter.Count;
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index f5c0030..aebce36 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -398,8 +398,14 @@
     host_slice = grpc_slice_from_copied_string(host);
     host_slice_ptr = &host_slice;
   }
-  return grpc_channel_create_call(channel, parent_call, propagation_mask, cq,
-                                  method_slice, host_slice_ptr, deadline, NULL);
+  grpc_call *ret =
+      grpc_channel_create_call(channel, parent_call, propagation_mask, cq,
+                               method_slice, host_slice_ptr, deadline, NULL);
+  grpc_slice_unref(method_slice);
+  if (host != NULL) {
+    grpc_slice_unref(host_slice);
+  }
+  return ret;
 }
 
 GPR_EXPORT grpc_connectivity_state GPR_CALLTYPE
@@ -790,7 +796,9 @@
     ops[nops].reserved = NULL;
     nops++;
   }
-  return grpcsharp_call_start_batch(call, ops, nops, ctx, NULL);
+  grpc_call_error ret = grpcsharp_call_start_batch(call, ops, nops, ctx, NULL);
+  grpc_slice_unref(status_details_slice);
+  return ret;
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
diff --git a/src/node/src/grpc_extension.js b/src/node/src/grpc_extension.js
index c13bf81..af43eac 100644
--- a/src/node/src/grpc_extension.js
+++ b/src/node/src/grpc_extension.js
@@ -16,6 +16,13 @@
  *
  */
 
+/**
+ * @module
+ * @private
+ */
+
+'use strict';
+
 var binary = require('node-pre-gyp/lib/pre-binding');
 var path = require('path');
 var binding_path =
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 8c750ea..d58d180 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -1363,3 +1363,50 @@
     call.cancel();
   });
 });
+describe('Client reconnect', function() {
+  var server;
+  var Client;
+  var client;
+  var port;
+  beforeEach(function() {
+    var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
+    var echo_service = test_proto.lookup('EchoService');
+    Client = grpc.loadObject(echo_service);
+    server = new grpc.Server();
+    server.addService(Client.service, {
+      echo: function(call, callback) {
+        callback(null, call.request);
+      }
+    });
+    port = server.bind('localhost:0', server_insecure_creds);
+    client = new Client('localhost:' + port, grpc.credentials.createInsecure());
+    server.start();
+  });
+  afterEach(function() {
+    server.forceShutdown();
+  });
+  it('should reconnect after server restart', function(done) {
+    client.echo({value: 'test value', value2: 3}, function(error, response) {
+      assert.ifError(error);
+      assert.deepEqual(response, {value: 'test value', value2: 3});
+      server.tryShutdown(function() {
+        server = new grpc.Server();
+        server.addService(Client.service, {
+          echo: function(call, callback) {
+            callback(null, call.request);
+          }
+        });
+        server.bind('localhost:' + port, server_insecure_creds);
+        server.start();
+        client.echo(undefined, function(error, response) {
+          if (error) {
+            console.log(error);
+          }
+          assert.ifError(error);
+          assert.deepEqual(response, {value: '', value2: 0});
+          done();
+        });
+      });
+    });
+  });
+});
diff --git a/src/objective-c/tests/PluginTest/imported-with-dash.proto b/src/objective-c/tests/PluginTest/imported-with-dash.proto
new file mode 100644
index 0000000..c01bbec
--- /dev/null
+++ b/src/objective-c/tests/PluginTest/imported-with-dash.proto
@@ -0,0 +1,22 @@
+// Copyright 2017 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+syntax = "proto3";
+
+package grpc.testing;
+
+option objc_class_prefix = "RMT";
+
+message TestMessageImported {
+  int32 dummy = 1;
+}
diff --git a/src/objective-c/tests/PluginTest/test-dash-filename.proto b/src/objective-c/tests/PluginTest/test-dash-filename.proto
new file mode 100644
index 0000000..afbb603
--- /dev/null
+++ b/src/objective-c/tests/PluginTest/test-dash-filename.proto
@@ -0,0 +1,27 @@
+// Copyright 2017 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+syntax = "proto3";
+
+package grpc.testing;
+
+option objc_class_prefix = "RMT";
+
+import "imported-with-dash.proto";
+
+message TestMessage {
+  int32 dummy = 1;
+}
+
+service DummyService {
+}
diff --git a/src/objective-c/tests/build_tests.sh b/src/objective-c/tests/build_tests.sh
index 711a9cc..340044f 100755
--- a/src/objective-c/tests/build_tests.sh
+++ b/src/objective-c/tests/build_tests.sh
@@ -37,3 +37,4 @@
 
 echo "TIME:  $(date)"
 pod install
+
diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh
index 6f27d1c..8fa9439 100755
--- a/src/objective-c/tests/run_tests.sh
+++ b/src/objective-c/tests/run_tests.sh
@@ -23,6 +23,38 @@
 # Run the tests server.
 
 BINDIR=../../../bins/$CONFIG
+PROTOC=$BINDIR/protobuf/protoc
+PLUGIN=$BINDIR/grpc_objective_c_plugin
+
+rm -rf PluginTest/*pb*
+
+# Verify the output proto filename
+eval $PROTOC \
+    --plugin=protoc-gen-grpc=$PLUGIN \
+    --objc_out=PluginTest \
+    --grpc_out=PluginTest \
+    -I PluginTest \
+    -I ../../../third_party/protobuf/src \
+    PluginTest/*.proto
+
+[ -e ./PluginTest/TestDashFilename.pbrpc.h ] || {
+    echo >&2 "protoc outputs wrong filename."
+    exit 1
+}
+
+# Verify names of the imported protos in generated code
+[ "`cat PluginTest/TestDashFilename.pbrpc.h |
+    egrep '#import ".*\.pb(objc|rpc)\.h"$' |
+    egrep '-'`" ] && {
+    echo >&2 "protoc generated import with wrong filename."
+    exit 1
+}
+[ "`cat PluginTest/TestDashFilename.pbrpc.m |
+    egrep '#import ".*\.pb(objc|rpc)\.m"$' |
+    egrep '-'`" ] && {
+    echo >&2 "protoc generated import with wrong filename."
+    exit 1
+}
 
 [ -f $BINDIR/interop_server ] || {
     echo >&2 "Can't find the test server. Make sure run_tests.py is making" \
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 2e8f0f2..744028b 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define PHP_GRPC_VERSION "1.5.0"
+#define PHP_GRPC_VERSION "1.5.0dev"
 
 #endif /* VERSION_H */
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 9359431..cd686a1 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -105,6 +105,15 @@
           ]
         }, {
           'conditions': [
+            ["target_arch=='ia32'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
+            }],
+            ["target_arch=='x64'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
+            }],
+            ["target_arch=='arm'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
+            }],
             ['grpc_alpn=="true"', {
               'defines': [
                 'TSI_OPENSSL_ALPN_SUPPORT=1'
@@ -117,17 +126,6 @@
           ],
           'include_dirs': [
             '<(node_root_dir)/deps/openssl/openssl/include',
-          ],
-          'conditions': [
-           ["target_arch=='ia32'", {
-               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
-           }],
-           ["target_arch=='x64'", {
-               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
-           }],
-           ["target_arch=='arm'", {
-               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
-           }]
           ]
         }],
         ['OS == "win"', {
diff --git a/templates/config.w32.template b/templates/config.w32.template
index c822eae..4edef96 100644
--- a/templates/config.w32.template
+++ b/templates/config.w32.template
@@ -28,4 +28,40 @@
       "/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+
       "/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+
       "/I"+configure_module_dirname+"\\third_party\\zlib");
+  <%
+    dirs = {}
+    for lib in libs:
+      if lib.name in php_config_m4.get('deps', []) and lib.name != 'ares':
+        for source in lib.src:
+          tmp = source
+          prev = ''
+          while (True):
+            idx = tmp.find('/');
+            if (idx == -1):
+              break
+            dirs[prev + '\\\\' + tmp[:idx]] = 1
+            prev += ('\\\\' + tmp[:idx]);
+            tmp = tmp[idx+1:]
+            
+    dirs['\\\\src'] = 1;
+    dirs['\\\\src\\\\php'] = 1;
+    dirs['\\\\src\\\\php\\\\ext'] = 1;
+    dirs['\\\\src\\\\php\\\\ext\\\\grpc'] = 1;
+    dirs = dirs.keys()
+    dirs.sort()
+  %>
+    base_dir = get_define('BUILD_DIR');
+    FSO.CreateFolder(base_dir+"\\ext");
+    FSO.CreateFolder(base_dir+"\\ext\\grpc");
+    % for dir in dirs:
+    FSO.CreateFolder(base_dir+"\\ext\\grpc${dir}");
+    % endfor
+    _build_dirs = new Array();
+    for (i = 0; i < build_dirs.length; i++) {
+      if (build_dirs[i].indexOf('grpc') == -1) {
+        _build_dirs[_build_dirs.length] = build_dirs[i];
+      }
+    }
+    build_dirs = _build_dirs;
+
   }
diff --git a/templates/package.json.template b/templates/package.json.template
index f573c43..92b2332 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -35,7 +35,7 @@
       "arguejs": "^0.2.3",
       "lodash": "^4.15.0",
       "nan": "^2.0.0",
-      "node-pre-gyp": "^0.6.0",
+      "node-pre-gyp": "^0.6.35",
       "protobufjs": "^5.0.0"
     },
     "devDependencies": {
diff --git a/templates/src/php/ext/grpc/version.h.template b/templates/src/php/ext/grpc/version.h.template
index 8436e02..0a7cfb3 100644
--- a/templates/src/php/ext/grpc/version.h.template
+++ b/templates/src/php/ext/grpc/version.h.template
@@ -22,6 +22,6 @@
   #ifndef VERSION_H
   #define VERSION_H
 
-  #define PHP_GRPC_VERSION "${settings.php_version.php_composer()}"
+  #define PHP_GRPC_VERSION "${settings.php_version.php()}"
 
   #endif /* VERSION_H */
diff --git a/test/distrib/node/run_distrib_test.sh b/test/distrib/node/run_distrib_test.sh
index bfd4ce9..a806f84 100755
--- a/test/distrib/node/run_distrib_test.sh
+++ b/test/distrib/node/run_distrib_test.sh
@@ -34,8 +34,8 @@
 
 STATIC_SERVER=127.0.0.1
 # If port_server is running, get port from that. Otherwise, assume we're in
-# docker and use 8080
-STATIC_PORT=$(curl 'localhost:32767/get' || echo '8080')
+# docker and use 12345
+STATIC_PORT=$(curl 'localhost:32767/get' || echo '12345')
 
 # Serves the input_artifacts directory statically at localhost:
 static "$EXTERNAL_GIT_ROOT/input_artifacts" -a $STATIC_SERVER -p $STATIC_PORT &
diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.sh b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.sh
deleted file mode 100755
index 859b03d..0000000
--- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -ex
-
-# change to grpc repo root
-cd $(dirname $0)/../../../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-tools/run_tests/run_tests_matrix.py -f c asan --inner_jobs 16 -j 1 --internal_ci --filter_pr_tests --base_branch origin/master --max_time=3600
diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.sh b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.sh
deleted file mode 100755
index b64148f..0000000
--- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -ex
-
-# change to grpc repo root
-cd $(dirname $0)/../../../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-tools/run_tests/run_tests_matrix.py -f c msan --inner_jobs 16 -j 1 --internal_ci --filter_pr_tests --base_branch origin/master --max_time=3600
diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.sh b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.sh
deleted file mode 100755
index 4fe0637..0000000
--- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -ex
-
-# change to grpc repo root
-cd $(dirname $0)/../../../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-tools/run_tests/run_tests_matrix.py -f c tsan --inner_jobs 16 -j 1 --internal_ci --filter_pr_tests --base_branch origin/master --max_time=3600
diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.sh b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.sh
deleted file mode 100755
index af57f6e..0000000
--- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -ex
-
-# change to grpc repo root
-cd $(dirname $0)/../../../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-tools/run_tests/run_tests_matrix.py -f c ubsan --inner_jobs 16 -j 1 --internal_ci --filter_pr_tests --base_branch origin/master --max_time=3600
diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.sh b/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.sh
deleted file mode 100755
index 59f1799..0000000
--- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -ex
-
-# change to grpc repo root
-cd $(dirname $0)/../../../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-tools/run_tests/run_tests_matrix.py -f c++ asan --inner_jobs 16 -j 1 --internal_ci --filter_pr_tests --base_branch origin/master --max_time=3600
diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.sh b/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.sh
deleted file mode 100755
index fb1aae7..0000000
--- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -ex
-
-# change to grpc repo root
-cd $(dirname $0)/../../../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-tools/run_tests/run_tests_matrix.py -f c++ tsan --inner_jobs 16 -j 1 --internal_ci --filter_pr_tests --base_branch origin/master --max_time=3600
diff --git a/tools/run_tests/artifacts/build_artifact_node.bat b/tools/run_tests/artifacts/build_artifact_node.bat
index a71db79..cca6563 100644
--- a/tools/run_tests/artifacts/build_artifact_node.bat
+++ b/tools/run_tests/artifacts/build_artifact_node.bat
@@ -12,7 +12,7 @@
 @rem See the License for the specific language governing permissions and
 @rem limitations under the License.
 
-set node_versions=4.0.0 5.0.0 6.0.0 7.0.0
+set node_versions=4.0.0 5.0.0 6.0.0 7.0.0 8.0.0
 
 set electron_versions=1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0
 
@@ -30,13 +30,13 @@
 @rem Try again after removing openssl headers
   rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\%%v\include\node\openssl" /S /Q
   rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\iojs-%%v\include\node\openssl" /S /Q
-  call .\node_modules\.bin\node-pre-gyp.cmd build package testpackage --target=%%v --target_arch=%1 || goto :error
+  call .\node_modules\.bin\node-pre-gyp.cmd build package --target=%%v --target_arch=%1 || goto :error
 
   xcopy /Y /I /S build\stage\* %ARTIFACTS_OUT%\ || goto :error
 )
 
 for %%v in (%electron_versions%) do (
-  cmd /V /C "set "HOME=%HOMEDRIVE%%HOMEPATH%\electron-gyp" && call .\node_modules\.bin\node-pre-gyp.cmd configure rebuild package testpackage --runtime=electron --target=%%v --target_arch=%1 --disturl=https://atom.io/download/electron" || goto :error
+  cmd /V /C "set "HOME=%HOMEDRIVE%%HOMEPATH%\electron-gyp" && call .\node_modules\.bin\node-pre-gyp.cmd configure rebuild package --runtime=electron --target=%%v --target_arch=%1 --disturl=https://atom.io/download/electron" || goto :error
 
   xcopy /Y /I /S build\stage\* %ARTIFACTS_OUT%\ || goto :error
 )
diff --git a/tools/run_tests/artifacts/build_artifact_node.sh b/tools/run_tests/artifacts/build_artifact_node.sh
index 5f7f7d2..9d39083 100755
--- a/tools/run_tests/artifacts/build_artifact_node.sh
+++ b/tools/run_tests/artifacts/build_artifact_node.sh
@@ -27,18 +27,18 @@
 
 npm update
 
-node_versions=( 4.0.0 5.0.0 6.0.0 7.0.0 )
+node_versions=( 4.0.0 5.0.0 6.0.0 7.0.0 8.0.0 )
 
 electron_versions=( 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 )
 
 for version in ${node_versions[@]}
 do
-  ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH --grpc_alpine=true
+  ./node_modules/.bin/node-pre-gyp configure rebuild package --target=$version --target_arch=$NODE_TARGET_ARCH --grpc_alpine=true
   cp -r build/stage/* "${ARTIFACTS_OUT}"/
 done
 
 for version in ${electron_versions[@]}
 do
-  HOME=~/.electron-gyp ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --runtime=electron --target=$version --target_arch=$NODE_TARGET_ARCH --disturl=https://atom.io/download/electron
+  HOME=~/.electron-gyp ./node_modules/.bin/node-pre-gyp configure rebuild package --runtime=electron --target=$version --target_arch=$NODE_TARGET_ARCH --disturl=https://atom.io/download/electron
   cp -r build/stage/* "${ARTIFACTS_OUT}"/
 done
diff --git a/tools/run_tests/helper_scripts/pre_build_node.bat b/tools/run_tests/helper_scripts/pre_build_node.bat
index ff4d98a..ececc57 100644
--- a/tools/run_tests/helper_scripts/pre_build_node.bat
+++ b/tools/run_tests/helper_scripts/pre_build_node.bat
@@ -14,5 +14,7 @@
 
 set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
 
-@rem Expire cache after 1 day
-call npm update --cache-min 86400
+@rem Update npm to at least version 5
+call npm update -g npm
+
+call npm update --prefer-online
diff --git a/tools/run_tests/helper_scripts/pre_build_node.sh b/tools/run_tests/helper_scripts/pre_build_node.sh
index 5d14a54..f41da71 100755
--- a/tools/run_tests/helper_scripts/pre_build_node.sh
+++ b/tools/run_tests/helper_scripts/pre_build_node.sh
@@ -20,10 +20,12 @@
 nvm install $NODE_VERSION
 set -ex
 
+# Update npm to at least version 5
+npm update -g npm
+
 export GRPC_CONFIG=${CONFIG:-opt}
 
-# Expire cache after 1 day
-npm update --cache-min 86400
+npm update --prefer-online
 
 npm install node-gyp-install
 ./node_modules/.bin/node-gyp-install
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 5f01820..6541ebc 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -450,10 +450,11 @@
     # we should specify in the compiler argument
     _check_compiler(self.args.compiler, ['default', 'node0.12',
                                          'node4', 'node5', 'node6',
-                                         'node7', 'electron1.3', 'electron1.6'])
+                                         'node7', 'node8',
+                                         'electron1.3', 'electron1.6'])
     if self.args.compiler == 'default':
       self.runtime = 'node'
-      self.node_version = '7'
+      self.node_version = '8'
     else:
       if self.args.compiler.startswith('electron'):
         self.runtime = 'electron'
@@ -1192,7 +1193,7 @@
                            'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
                            'vs2013', 'vs2015',
                            'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3', 'python_alpine',
-                           'node0.12', 'node4', 'node5', 'node6', 'node7',
+                           'node0.12', 'node4', 'node5', 'node6', 'node7', 'node8',
                            'electron1.3', 'electron1.6',
                            'coreclr',
                            'cmake'],
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 96e865b..635d87f 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -287,6 +287,15 @@
                               extra_args=extra_args,
                               inner_jobs=inner_jobs)
 
+  test_jobs += _generate_jobs(languages=['node'],
+                              configs=['dbg'],
+                              platforms=['linux'],
+                              arch='default',
+                              compiler='node7',
+                              labels=['portability'],
+                              extra_args=extra_args,
+                              inner_jobs=inner_jobs)
+
   return test_jobs