Polish grpcio_health_checking package

-Rename namespace to grpc_health->grpc to match spec
-Proper use of NOT_FOUND status code
-Improve testing
-Add source distribution to artifact build
diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in
index 7d26647..7407f64 100644
--- a/src/python/grpcio_health_checking/MANIFEST.in
+++ b/src/python/grpcio_health_checking/MANIFEST.in
@@ -1,3 +1,4 @@
+include grpc_version.py
 include health_commands.py
-graft grpc_health
+graft grpc
 global-exclude *.pyc
diff --git a/src/python/grpcio_health_checking/grpc_health/health/__init__.py b/src/python/grpcio_health_checking/grpc/__init__.py
similarity index 96%
rename from src/python/grpcio_health_checking/grpc_health/health/__init__.py
rename to src/python/grpcio_health_checking/grpc/__init__.py
index 7086519..fcc7048 100644
--- a/src/python/grpcio_health_checking/grpc_health/health/__init__.py
+++ b/src/python/grpcio_health_checking/grpc/__init__.py
@@ -27,4 +27,4 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/src/python/grpcio_health_checking/grpc_health/__init__.py b/src/python/grpcio_health_checking/grpc/health/__init__.py
similarity index 100%
rename from src/python/grpcio_health_checking/grpc_health/__init__.py
rename to src/python/grpcio_health_checking/grpc/health/__init__.py
diff --git a/src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py
similarity index 100%
rename from src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py
rename to src/python/grpcio_health_checking/grpc/health/v1/__init__.py
diff --git a/src/python/grpcio_health_checking/grpc_health/health/v1/health.py b/src/python/grpcio_health_checking/grpc/health/v1/health.py
similarity index 81%
rename from src/python/grpcio_health_checking/grpc_health/health/v1/health.py
rename to src/python/grpcio_health_checking/grpc/health/v1/health.py
index 8da60c7..8108ac1 100644
--- a/src/python/grpcio_health_checking/grpc_health/health/v1/health.py
+++ b/src/python/grpcio_health_checking/grpc/health/v1/health.py
@@ -31,10 +31,12 @@
 
 import threading
 
-from grpc_health.health.v1 import health_pb2
+import grpc
+
+from grpc.health.v1 import health_pb2
 
 
-class HealthServicer(health_pb2.BetaHealthServicer):
+class HealthServicer(health_pb2.HealthServicer):
   """Servicer handling RPCs for service statuses."""
 
   def __init__(self):
@@ -43,14 +45,12 @@
 
   def Check(self, request, context):
     with self._server_status_lock:
-      if request.service not in self._server_status:
-        # TODO(atash): once the Python API has a way of setting the server
-        # status, bring us into conformance with the health check spec by
-        # returning the NOT_FOUND status here.
-        raise NotImplementedError()
+      status = self._server_status.get(request.service)
+      if status is None:
+        context.set_code(grpc.StatusCode.NOT_FOUND)
+        return health_pb2.HealthCheckResponse()
       else:
-        return health_pb2.HealthCheckResponse(
-            status=self._server_status[request.service])
+        return health_pb2.HealthCheckResponse(status=status)
 
   def set(self, service, status):
     """Sets the status of a service.
@@ -63,4 +63,3 @@
     """
     with self._server_status_lock:
       self._server_status[service] = status
-
diff --git a/src/python/grpcio_health_checking/grpc_health/health/__init__.py b/src/python/grpcio_health_checking/grpc_version.py
similarity index 89%
copy from src/python/grpcio_health_checking/grpc_health/health/__init__.py
copy to src/python/grpcio_health_checking/grpc_version.py
index 7086519..2e48fde 100644
--- a/src/python/grpcio_health_checking/grpc_health/health/__init__.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +27,6 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
+VERSION='1.0.0rc1'
diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py
index a7a59f6..66df25d 100644
--- a/src/python/grpcio_health_checking/health_commands.py
+++ b/src/python/grpcio_health_checking/health_commands.py
@@ -29,16 +29,10 @@
 
 """Provides distutils command classes for the GRPC Python setup process."""
 
-import distutils
-import glob
 import os
-import os.path
 import shutil
-import subprocess
-import sys
 
 import setuptools
-from setuptools.command import build_py
 
 ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
 HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto')
@@ -60,12 +54,25 @@
     if os.path.isfile(HEALTH_PROTO):
       shutil.copyfile(
           HEALTH_PROTO,
-          os.path.join(ROOT_DIR, 'grpc_health/health/v1/health.proto'))
+          os.path.join(ROOT_DIR, 'grpc/health/v1/health.proto'))
 
 
-class BuildPy(build_py.build_py):
-  """Custom project build command."""
+class BuildPackageProtos(setuptools.Command):
+  """Command to generate project *_pb2.py modules from proto files."""
+
+  description = 'build grpc protobuf modules'
+  user_options = []
+
+  def initialize_options(self):
+    pass
+
+  def finalize_options(self):
+    pass
 
   def run(self):
-    self.run_command('build_proto_modules')
-    build_py.build_py.run(self)
+    # due to limitations of the proto generator, we require that only *one*
+    # directory is provided as an 'include' directory. We assume it's the '' key
+    # to `self.distribution.package_dir` (and get a key error if it's not
+    # there).
+    from grpc.tools import command
+    command.build_package_protos(self.distribution.package_dir[''])
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 70b4575..727d628 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -30,49 +30,42 @@
 """Setup module for the GRPC Python package's optional health checking."""
 
 import os
-import os.path
 import sys
 
-from distutils import core as _core
 import setuptools
 
-import grpc.tools.command
-
 # Ensure we're in the proper directory whether or not we're being used by pip.
 os.chdir(os.path.dirname(os.path.abspath(__file__)))
 
 # Break import-style to ensure we can actually find our commands module.
 import health_commands
-
-PACKAGES = (
-    setuptools.find_packages('.')
-)
+import grpc_version
 
 PACKAGE_DIRECTORIES = {
     '': '.',
 }
 
 SETUP_REQUIRES = (
-    'grpcio-tools>=0.14.0',
+    'grpcio-tools>=0.15.0',
 )
 
 INSTALL_REQUIRES = (
-    'grpcio>=0.13.1',
+    'grpcio>=0.15.0',
 )
 
 COMMAND_CLASS = {
     # Run preprocess from the repository *before* doing any packaging!
     'preprocess': health_commands.CopyProtoModules,
-
-    'build_proto_modules': grpc.tools.command.BuildProtoModules,
-    'build_py': health_commands.BuildPy,
+    'build_package_protos': health_commands.BuildPackageProtos,
 }
 
 setuptools.setup(
     name='grpcio-health-checking',
-    version='0.14.0',
-    packages=list(PACKAGES),
+    version=grpc_version.VERSION,
+    license='3-clause BSD',
     package_dir=PACKAGE_DIRECTORIES,
+    packages=setuptools.find_packages('.'),
+    namespace_packages=['grpc'],
     install_requires=INSTALL_REQUIRES,
     setup_requires=SETUP_REQUIRES,
     cmdclass=COMMAND_CLASS
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index 171829b..5ee551c 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -138,7 +138,7 @@
 
   def run(self):
     try:
-      self.run_command('build_proto_modules')
+      self.run_command('build_package_protos')
     except CommandError as error:
       sys.stderr.write('warning: %s\n' % error.message)
     build_py.build_py.run(self)
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 7eef420..0afaf7d 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -75,7 +75,7 @@
     # Run `preprocess` *before* doing any packaging!
     'preprocess': commands.GatherProto,
 
-    'build_proto_modules': grpc.tools.command.BuildProtoModules,
+    'build_package_protos': grpc.tools.command.BuildPackageProtos,
     'build_py': commands.BuildPy,
     'run_interop': commands.RunInterop,
     'test_lite': commands.TestLite
diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
index 1b63388..80300d1 100644
--- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
+++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
@@ -27,48 +27,68 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Tests of grpc_health.health.v1.health."""
+"""Tests of grpc.health.v1.health."""
 
 import unittest
 
-from grpc_health.health.v1 import health
-from grpc_health.health.v1 import health_pb2
+import grpc
+from grpc.framework.foundation import logging_pool
+from grpc.health.v1 import health
+from grpc.health.v1 import health_pb2
+
+from tests.unit.framework.common import test_constants
 
 
 class HealthServicerTest(unittest.TestCase):
 
   def setUp(self):
-    self.servicer = health.HealthServicer()
-    self.servicer.set('', health_pb2.HealthCheckResponse.SERVING)
-    self.servicer.set('grpc.test.TestServiceServing',
-                      health_pb2.HealthCheckResponse.SERVING)
-    self.servicer.set('grpc.test.TestServiceUnknown',
-                      health_pb2.HealthCheckResponse.UNKNOWN)
-    self.servicer.set('grpc.test.TestServiceNotServing',
-                      health_pb2.HealthCheckResponse.NOT_SERVING)
+    servicer = health.HealthServicer()
+    servicer.set('', health_pb2.HealthCheckResponse.SERVING)
+    servicer.set('grpc.test.TestServiceServing',
+                 health_pb2.HealthCheckResponse.SERVING)
+    servicer.set('grpc.test.TestServiceUnknown',
+                 health_pb2.HealthCheckResponse.UNKNOWN)
+    servicer.set('grpc.test.TestServiceNotServing',
+                 health_pb2.HealthCheckResponse.NOT_SERVING)
+    server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+    self._server = grpc.server(server_pool)
+    port = self._server.add_insecure_port('[::]:0')
+    health_pb2.add_HealthServicer_to_server(servicer, self._server)
+    self._server.start()
+
+    channel = grpc.insecure_channel('localhost:%d' % port)
+    self._stub = health_pb2.HealthStub(channel)
 
   def test_empty_service(self):
     request = health_pb2.HealthCheckRequest()
-    resp = self.servicer.Check(request, None)
-    self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING)
+    resp = self._stub.Check(request)
+    self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
 
   def test_serving_service(self):
     request = health_pb2.HealthCheckRequest(
         service='grpc.test.TestServiceServing')
-    resp = self.servicer.Check(request, None)
-    self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING)
+    resp = self._stub.Check(request)
+    self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
 
   def test_unknown_serivce(self):
     request = health_pb2.HealthCheckRequest(
         service='grpc.test.TestServiceUnknown')
-    resp = self.servicer.Check(request, None)
-    self.assertEqual(resp.status, health_pb2.HealthCheckResponse.UNKNOWN)
+    resp = self._stub.Check(request)
+    self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status)
 
   def test_not_serving_service(self):
     request = health_pb2.HealthCheckRequest(
         service='grpc.test.TestServiceNotServing')
-    resp = self.servicer.Check(request, None)
-    self.assertEqual(resp.status, health_pb2.HealthCheckResponse.NOT_SERVING)
+    resp = self._stub.Check(request)
+    self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status)
+
+  def test_not_found_service(self):
+    request = health_pb2.HealthCheckRequest(
+        service='not-found')
+    with self.assertRaises(grpc.RpcError) as context:
+      resp = self._stub.Check(request)
+  
+    self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code())
 
 
 if __name__ == '__main__':