diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
index 67cee19914d123ad478969cc61874a05bae346ba..b9216571ef09da6e18a8b1ea7de248c362b7741b 100644
--- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
@@ -115,6 +115,14 @@ RUN cd llvm-build && cmake \
   ../llvm
 RUN make -C llvm-build -j 12 && make -C llvm-build install && rm -rf llvm-build
 
+#================
+# libuv
+RUN cd /tmp \
+    && wget http://dist.libuv.org/dist/v1.9.1/libuv-v1.9.1.tar.gz \
+    && tar -xf libuv-v1.9.1.tar.gz \
+    && cd libuv-v1.9.1 \
+    && sh autogen.sh && ./configure --prefix=/usr && make && make install
+
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
 RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index e8818d77e067822356066acbc4063688eeba257b..a146ac8f6656fb0afc11f7d358d3ee9d51356689 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -207,11 +207,11 @@ class CLanguage(object):
       cflags = '-DGRPC_UV '
       try:
         cflags += subprocess.check_output(['pkg-config', '--cflags', 'libuv']).strip() + ' '
-      except subprocess.CalledProcessError:
+      except (subprocess.CalledProcessError, OSError):
         pass
       try:
         ldflags = subprocess.check_output(['pkg-config', '--libs', 'libuv']).strip() + ' '
-      except subprocess.CalledProcessError:
+      except (subprocess.CalledProcessError, OSError):
         ldflags = '-luv '
       self._make_options += ['EXTRA_CPPFLAGS={}'.format(cflags),
                              'EXTRA_LDLIBS={}'.format(ldflags)]
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index a94f9cfef5e1ed777b09e64cbf93b47941c9ee2b..ca459fbdbd2b73254e127338900be8a5d38b3b69 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -111,28 +111,28 @@ def _create_test_jobs(extra_args=[]):
                              platforms=['linux'],
                              labels=['basictests'],
                              extra_args=extra_args)
-  
+
   # supported on all platforms.
   test_jobs += _generate_jobs(languages=['c', 'csharp', 'node', 'python'],
                              configs=['dbg', 'opt'],
                              platforms=['linux', 'macos', 'windows'],
                              labels=['basictests'],
                              extra_args=extra_args)
-  
+
   # supported on linux and mac.
   test_jobs += _generate_jobs(languages=['c++', 'ruby', 'php'],
                               configs=['dbg', 'opt'],
                               platforms=['linux', 'macos'],
                               labels=['basictests'],
                               extra_args=extra_args)
-  
+
   # supported on mac only.
   test_jobs += _generate_jobs(languages=['objc'],
                               configs=['dbg', 'opt'],
                               platforms=['macos'],
                               labels=['basictests'],
                               extra_args=extra_args)
-  
+
   # sanitizers
   test_jobs += _generate_jobs(languages=['c'],
                               configs=['msan', 'asan', 'tsan'],
@@ -144,9 +144,17 @@ def _create_test_jobs(extra_args=[]):
                               platforms=['linux'],
                               labels=['sanitizers'],
                               extra_args=extra_args)
+
+  # libuv tests
+  test_jobs += _generate_jobs(languages=['c'],
+                              configs=['dbg', 'opt'],
+                              platforms=['linux'],
+                              labels=['libuv'],
+                              extra_args=extra_args + ['--iomgr_platform=uv'])
+
   return test_jobs
 
-  
+
 def _create_portability_test_jobs(extra_args=[]):
   test_jobs = []
   # portability C x86
@@ -157,7 +165,7 @@ def _create_portability_test_jobs(extra_args=[]):
                               compiler='default',
                               labels=['portability'],
                               extra_args=extra_args)
-  
+
   # portability C and C++ on x64
   for compiler in ['gcc4.4', 'gcc4.6', 'gcc5.3',
                    'clang3.5', 'clang3.6', 'clang3.7']:
@@ -168,7 +176,7 @@ def _create_portability_test_jobs(extra_args=[]):
                                 compiler=compiler,
                                 labels=['portability'],
                                 extra_args=extra_args)
-  
+
   # portability C on Windows
   for arch in ['x86', 'x64']:
     for compiler in ['vs2013', 'vs2015']:
@@ -179,7 +187,7 @@ def _create_portability_test_jobs(extra_args=[]):
                                   compiler=compiler,
                                   labels=['portability'],
                                   extra_args=extra_args)
-  
+
   test_jobs += _generate_jobs(languages=['python'],
                               configs=['dbg'],
                               platforms=['linux'],
@@ -187,7 +195,7 @@ def _create_portability_test_jobs(extra_args=[]):
                               compiler='python3.4',
                               labels=['portability'],
                               extra_args=extra_args)
-  
+
   test_jobs += _generate_jobs(languages=['csharp'],
                               configs=['dbg'],
                               platforms=['linux'],
@@ -195,7 +203,7 @@ def _create_portability_test_jobs(extra_args=[]):
                               compiler='coreclr',
                               labels=['portability'],
                               extra_args=extra_args)
-  return test_jobs  
+  return test_jobs
 
 
 def _allowed_labels():
@@ -248,12 +256,12 @@ if not jobs:
   jobset.message('FAILED', 'No test suites match given criteria.',
                  do_newline=True)
   sys.exit(1)
-  
+
 print('IMPORTANT: The changes you are testing need to be locally committed')
 print('because only the committed changes in the current branch will be')
 print('copied to the docker environment or into subworkspaces.')
 
-print 
+print
 print 'Will run these tests:'
 for job in jobs:
   if args.dry_run: