Merge pull request #5039 from vjpai/limit_cores

Fix core limit dummy code for non-Linux cases
diff --git a/.gitignore b/.gitignore
index cf05a2c..9a1dc00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,9 @@
 # Makefile's cache
 cache.mk
 
+# Ruby's local gem information
+Gemfile.lock
+
 # Temporary test reports
 report.xml
 latency_trace.txt
diff --git a/Makefile b/Makefile
index 87a8ade..442e154 100644
--- a/Makefile
+++ b/Makefile
@@ -336,7 +336,7 @@
 endif
 
 ifeq ($(SYSTEM),Linux)
-LIBS = rt m pthread
+LIBS = dl rt m pthread
 LDFLAGS += -pthread
 endif
 
diff --git a/binding.gyp b/binding.gyp
index aa06024..e76ea54 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -44,7 +44,10 @@
     ],
     'conditions': [
       ['OS == "win"', {
-        "include_dirs": [ "third_party/boringssl/include" ],
+        "include_dirs": [
+          "third_party/boringssl/include",
+          "third_party/zlib"
+        ],
         "defines": [
           '_WIN32_WINNT=0x0600',
           'WIN32_LEAN_AND_MEAN',
@@ -63,19 +66,20 @@
           "ws2_32"
         ]
       }, { # OS != "win"
+        'variables': {
+          'config': '<!(echo $CONFIG)',
+          # The output of "node --version" is "v[version]". We use cut to
+          # remove the first character.
+          'target%': '<!(node --version | cut -c2-)'
+        },
           # Empirically, Node only exports ALPN symbols if its major version is >0.
           # io.js always reports versions >0 and always exports ALPN symbols.
           # Therefore, Node's major version will be truthy if and only if it
-          # supports ALPN. The output of "node -v" is v[major].[minor].[patch],
-          # like "v4.1.1" in a recent version. We use cut to split by period and
-          # take the first field (resulting in "v[major]"), then use cut again
-          # to take all but the first character, removing the "v".
+          # supports ALPN. The target is "[major].[minor].[patch]". We split by
+          # periods and take the first field to get the major version.
         'defines': [
-          'TSI_OPENSSL_ALPN_SUPPORT=<!(node --version | cut -d. -f1 | cut -c2-)'
+          'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)'
         ],
-        'variables': {
-          'config': '<!(echo $CONFIG)'
-        },
         'include_dirs': [
           '<(node_root_dir)/deps/openssl/openssl/include',
           '<(node_root_dir)/deps/zlib'
@@ -713,7 +717,8 @@
           'xcode_settings': {
             'MACOSX_DEPLOYMENT_TARGET': '10.9',
             'OTHER_CFLAGS': [
-              '-stdlib=libc++'
+              '-stdlib=libc++',
+              '-std=c++11'
             ]
           }
         }],
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index ee3443c..92daab9 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -208,6 +208,14 @@
     goto error;
   }
 
+  state->server = server;
+  state->tcp = tcp;
+  state->sc = sc;
+  state->creds = grpc_server_credentials_ref(creds);
+  state->is_shutdown = 0;
+  gpr_mu_init(&state->mu);
+  gpr_ref_init(&state->refcount, 1);
+
   for (i = 0; i < resolved->naddrs; i++) {
     port_temp = grpc_tcp_server_add_port(
         tcp, (struct sockaddr *)&resolved->addrs[i].addr,
@@ -233,14 +241,6 @@
   }
   grpc_resolved_addresses_destroy(resolved);
 
-  state->server = server;
-  state->tcp = tcp;
-  state->sc = sc;
-  state->creds = grpc_server_credentials_ref(creds);
-
-  state->is_shutdown = 0;
-  gpr_mu_init(&state->mu);
-  gpr_ref_init(&state->refcount, 1);
 
   /* Register with the server only upon success */
   grpc_server_add_listener(&exec_ctx, server, state, start, destroy);
@@ -250,17 +250,18 @@
 
 /* Error path: cleanup and return */
 error:
-  if (sc) {
-    GRPC_SECURITY_CONNECTOR_UNREF(sc, "server");
-  }
   if (resolved) {
     grpc_resolved_addresses_destroy(resolved);
   }
   if (tcp) {
     grpc_tcp_server_unref(&exec_ctx, tcp);
-  }
-  if (state) {
-    gpr_free(state);
+  } else {
+    if (sc) {
+      GRPC_SECURITY_CONNECTOR_UNREF(sc, "server");
+    }
+    if (state) {
+      gpr_free(state);
+    }
   }
   grpc_exec_ctx_finish(&exec_ctx);
   return 0;
diff --git a/src/core/support/env_linux.c b/src/core/support/env_linux.c
index b5832a5..442cd82 100644
--- a/src/core/support/env_linux.c
+++ b/src/core/support/env_linux.c
@@ -42,33 +42,23 @@
 
 #include "src/core/support/env.h"
 
+#include <dlfcn.h>
 #include <stdlib.h>
 
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include <grpc/support/useful.h>
 
 #include "src/core/support/string.h"
 
-/* Declare weak symbols for versions of secure_getenv that *may* be
- * on a users machine. Older libc's call this __secure_getenv, even
- * older don't support the functionality.
- *
- * If a symbol is not present, these will be equal to NULL.
- */
-char *__attribute__((weak)) secure_getenv(const char *name);
-char *__attribute__((weak)) __secure_getenv(const char *name);
-
 char *gpr_getenv(const char *name) {
-  static char *(*getenv_func)(const char *) = secure_getenv;
+  typedef char *(*getenv_type)(const char *);
+  static getenv_type getenv_func = NULL;
   /* Check to see which getenv variant is supported (go from most
    * to least secure) */
-  if (getenv_func == NULL) {
-    getenv_func = __secure_getenv;
-    if (getenv_func == NULL) {
-      gpr_log(GPR_DEBUG,
-              "No secure_getenv. Please consider upgrading your libc.");
-      getenv_func = getenv;
-    }
+  const char *names[] = {"secure_getenv", "__secure_getenv", "getenv"};
+  for (size_t i = 0; getenv_func == NULL && i < GPR_ARRAY_SIZE(names); i++) {
+    getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]);
   }
   char *result = getenv_func(name);
   return result == NULL ? result : gpr_strdup(result);
diff --git a/src/core/support/wrap_memcpy.c b/src/core/support/wrap_memcpy.c
index ac30668..15c289f 100644
--- a/src/core/support/wrap_memcpy.c
+++ b/src/core/support/wrap_memcpy.c
@@ -42,9 +42,12 @@
 #ifdef __linux__
 #ifdef __x86_64__
 __asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
-#endif
-
 void *__wrap_memcpy(void *destination, const void *source, size_t num) {
   return memcpy(destination, source, num);
 }
+#else /* !__x86_64__ */
+void *__wrap_memcpy(void *destination, const void *source, size_t num) {
+  return memmove(destination, source, num);
+}
+#endif
 #endif
diff --git a/templates/Makefile.template b/templates/Makefile.template
index afe83a8..ef17d74 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -251,7 +251,7 @@
   endif
 
   ifeq ($(SYSTEM),Linux)
-  LIBS = rt m pthread
+  LIBS = dl rt m pthread
   LDFLAGS += -pthread
   endif
 
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 31c9f8c..7cee562 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -46,7 +46,10 @@
       ],
       'conditions': [
         ['OS == "win"', {
-          "include_dirs": [ "third_party/boringssl/include" ],
+          "include_dirs": [
+            "third_party/boringssl/include",
+            "third_party/zlib"
+          ],
           "defines": [
             '_WIN32_WINNT=0x0600',
             'WIN32_LEAN_AND_MEAN',
@@ -65,19 +68,20 @@
             "ws2_32"
           ]
         }, { # OS != "win"
+          'variables': {
+            'config': '<!(echo $CONFIG)',
+            # The output of "node --version" is "v[version]". We use cut to
+            # remove the first character.
+            'target%': '<!(node --version | cut -c2-)'
+          },
             # Empirically, Node only exports ALPN symbols if its major version is >0.
             # io.js always reports versions >0 and always exports ALPN symbols.
             # Therefore, Node's major version will be truthy if and only if it
-            # supports ALPN. The output of "node -v" is v[major].[minor].[patch],
-            # like "v4.1.1" in a recent version. We use cut to split by period and
-            # take the first field (resulting in "v[major]"), then use cut again
-            # to take all but the first character, removing the "v".
+            # supports ALPN. The target is "[major].[minor].[patch]". We split by
+            # periods and take the first field to get the major version.
           'defines': [
-            'TSI_OPENSSL_ALPN_SUPPORT=<!(node --version | cut -d. -f1 | cut -c2-)'
+            'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)'
           ],
-          'variables': {
-            'config': '<!(echo $CONFIG)'
-          },
           'include_dirs': [
             '<(node_root_dir)/deps/openssl/openssl/include',
             '<(node_root_dir)/deps/zlib'
@@ -218,7 +222,8 @@
             'xcode_settings': {
               'MACOSX_DEPLOYMENT_TARGET': '10.9',
               'OTHER_CFLAGS': [
-                '-stdlib=libc++'
+                '-stdlib=libc++',
+                '-std=c++11'
               ]
             }
           }],
diff --git a/test/core/surface/server_chttp2_test.c b/test/core/surface/server_chttp2_test.c
index ec7df6f..0a3652a 100644
--- a/test/core/surface/server_chttp2_test.c
+++ b/test/core/surface/server_chttp2_test.c
@@ -32,7 +32,14 @@
  */
 
 #include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include "src/core/security/credentials.h"
+#include "src/core/tsi/fake_transport_security.h"
+#include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
 void test_unparsable_target(void) {
@@ -40,10 +47,31 @@
   GPR_ASSERT(port == 0);
 }
 
+void test_add_same_port_twice() {
+  int port = grpc_pick_unused_port_or_die();
+  char *addr = NULL;
+  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+  grpc_server *server = grpc_server_create(NULL, NULL);
+  grpc_server_credentials *fake_creds =
+      grpc_fake_transport_security_server_credentials_create();
+  gpr_join_host_port(&addr, "localhost", port);
+  GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds));
+  GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds) == 0);
+
+  grpc_server_credentials_release(fake_creds);
+  gpr_free(addr);
+  grpc_server_shutdown_and_notify(server, cq, NULL);
+  grpc_completion_queue_pluck(cq, NULL, gpr_inf_future(GPR_CLOCK_REALTIME),
+                              NULL);
+  grpc_server_destroy(server);
+  grpc_completion_queue_destroy(cq);
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
   test_unparsable_target();
+  test_add_same_port_twice();
   grpc_shutdown();
   return 0;
 }
diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
index f467cff..41dc427 100644
--- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
@@ -58,6 +58,10 @@
   wget \
   zip && apt-get clean
 
+# Install Node dependencies
+RUN touch .profile
+RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
+RUN /bin/bash -l -c "nvm install 4 && npm install -g node-pre-gyp"
 
 ##################
 # Python dependencies
@@ -87,7 +91,6 @@
 RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
 RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
 
-
 RUN mkdir /var/local/jenkins
 
 # Define the default command.
diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
index 9522df7..46bc9f8 100644
--- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
@@ -58,6 +58,10 @@
   wget \
   zip && apt-get clean
 
+# Install Node dependencies
+RUN touch .profile
+RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
+RUN /bin/bash -l -c "nvm install 4 && npm install -g node-pre-gyp"
 
 ##################
 # Python dependencies
diff --git a/tools/jenkins/docker_run.sh b/tools/jenkins/docker_run.sh
index 7a0ee29..693e87c 100755
--- a/tools/jenkins/docker_run.sh
+++ b/tools/jenkins/docker_run.sh
@@ -43,4 +43,6 @@
 
 cd /var/local/git/grpc
 
+nvm use 4
+
 $RUN_COMMAND
diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py
index d0aee7d..317111e 100644
--- a/tools/run_tests/artifact_targets.py
+++ b/tools/run_tests/artifact_targets.py
@@ -183,16 +183,49 @@
   def __str__(self):
     return self.name
 
+node_gyp_arch_map = {
+  'x86': 'ia32',
+  'x64': 'x64'
+}
+
+class NodeExtArtifact:
+  """Builds Node native extension"""
+
+  def __init__(self, platform, arch):
+    self.name = 'node_ext_{0}_{1}'.format(platform, arch)
+    self.platform = platform
+    self.arch = arch
+    self.gyp_arch = node_gyp_arch_map[arch]
+    self.labels = ['artifact', 'node', platform, arch]
+
+  def pre_build_jobspecs(self):
+    return []
+
+  def build_jobspec(self):
+    if self.platform == 'windows':
+      return create_jobspec(self.name,
+                            ['tools\\run_tests\\build_artifact_node.bat',
+                             self.gyp_arch],
+                            shell=True)
+    else:
+      if self.platform == 'linux':
+        return create_docker_jobspec(
+            self.name,
+            'tools/dockerfile/grpc_artifact_linux_{}'.format(self.arch),
+            'tools/run_tests/build_artifact_node.sh {}'.format(self.gyp_arch))
+      else:
+        return create_jobspec(self.name,
+                              ['tools/run_tests/build_artifact_node.sh',
+                               self.gyp_arch])
+
 
 def targets():
   """Gets list of supported targets"""
-  return [CSharpExtArtifact('linux', 'x86'),
-          CSharpExtArtifact('linux', 'x64'),
-          CSharpExtArtifact('macos', 'x86'),
-          CSharpExtArtifact('macos', 'x64'),
-          CSharpExtArtifact('windows', 'x86'),
-          CSharpExtArtifact('windows', 'x64'),
-          PythonArtifact('linux', 'x86'),
-          PythonArtifact('linux', 'x64'),
-          RubyArtifact('linux', 'x86'),
-          RubyArtifact('linux', 'x64')]
+  return ([Cls(platform, arch)
+           for Cls in (CSharpExtArtifact, NodeExtArtifact)
+           for platform in ('linux', 'macos', 'windows')
+           for arch in ('x86', 'x64')] +
+          [PythonArtifact('linux', 'x86'),
+           PythonArtifact('linux', 'x64'),
+           RubyArtifact('linux', 'x86'),
+           RubyArtifact('linux', 'x64')])
diff --git a/tools/run_tests/build_artifact_node.bat b/tools/run_tests/build_artifact_node.bat
new file mode 100644
index 0000000..f150bb1
--- /dev/null
+++ b/tools/run_tests/build_artifact_node.bat
@@ -0,0 +1,55 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem     * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem     * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem     * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set node_versions=0.10.41 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0
+
+set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
+
+del /f /q BUILD || rmdir build /s /q
+
+call npm update || goto :error
+
+mkdir artifacts
+
+for %%v in (%node_versions%) do (
+  call node-pre-gyp configure build --target=%%v --target_arch=%1
+
+@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-pre-gyp build package testpackage --target=%%v --target_arch=%1 || goto :error
+
+  xcopy /Y /I /S build\stage\* artifacts\ || goto :error
+)
+if %errorlevel% neq 0 exit /b %errorlevel%
+
+goto :EOF
+
+:error
+exit /b 1
\ No newline at end of file
diff --git a/tools/run_tests/build_artifact_node.sh b/tools/run_tests/build_artifact_node.sh
new file mode 100755
index 0000000..ec3fb64
--- /dev/null
+++ b/tools/run_tests/build_artifact_node.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Copyright 2016, 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.
+
+set -ex
+
+cd $(dirname $0)/../..
+
+rm -rf build
+
+mkdir -p artifacts
+
+npm update
+
+node_versions=( 0.10.41 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 )
+
+for version in ${node_versions[@]}
+do
+  node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$1
+  cp -r build/stage/* artifacts/
+done
diff --git a/tools/run_tests/interop_html_report.template b/tools/run_tests/interop_html_report.template
index c01bdf7..114a508 100644
--- a/tools/run_tests/interop_html_report.template
+++ b/tools/run_tests/interop_html_report.template
@@ -46,15 +46,19 @@
     ## Because interop tests does not have runs_per_test flag, each test is 
     ## run once. So there should only be one element for each result.
     <% result = resultset[shortname][0] %>
-    <td bgcolor="white">
-      <div style="width:95%; border: 1px solid black; position: relative; padding: 3px;">
-        <span style="position: absolute; left: 45%;">${int(result.http2results['percent'] * 100)}&#37;</span>
-        <div style="height: 20px; 
-          background-color: hsl(${result.http2results['percent'] * 120}, 100%, 50%); 
-          width: ${result.http2results['percent'] * 100}%;"
-          title="${result.http2results['failed_cases'] | h}"></div>
-      </div>
-    </td>
+    % if result.http2results:
+      <td bgcolor="white">
+        <div style="width:95%; border: 1px solid black; position: relative; padding: 3px;">
+          <span style="position: absolute; left: 45%;">${int(result.http2results['percent'] * 100)}&#37;</span>
+          <div style="height: 20px; 
+            background-color: hsl(${result.http2results['percent'] * 120}, 100%, 50%); 
+            width: ${result.http2results['percent'] * 100}%;"
+            title="${result.http2results['failed_cases'] | h}"></div>
+        </div>
+      </td>
+    % else: 
+      <td bgcolor="red">No result is found!</td>
+    % endif
   % else:
      <td bgcolor="magenta">Not implemented</td>
   % endif