Fixed some changes
diff --git a/tools/run_tests/filter_pull_request_tests.py b/tools/run_tests/filter_pull_request_tests.py
index 6cc06d9..fe8b8ed 100644
--- a/tools/run_tests/filter_pull_request_tests.py
+++ b/tools/run_tests/filter_pull_request_tests.py
@@ -28,29 +28,101 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Filter out tests based on file differences compared to grpc:master"""
+"""Filter out tests based on file differences compared to merge target branch"""
 
 from subprocess import call, check_output
 
-# triggers to skip c++ tests
-run_cpp_starts_with_triggers = ('src/core',
-			        'src/cpp',
-			        'test/core',
-			        'test/cpp')
+# Whitelist for all tests
+# Update all instances in corresponding trigger lists when modifying this
+starts_with_whitelist = ['templates/',
+                         'doc/',
+                         'examples/',
+                         'summerofcode/',
+                         'src/cpp',
+                         'src/csharp',
+                         'src/node',
+                         'src/objective-c',
+                         'src/php',
+                         'src/python',
+                         'src/ruby',
+                         'test/core',
+                         'test/cpp',
+                         'test/distrib/cpp',
+                         'test/distrib/csharp',
+                         'test/distrib/node',
+                         'test/distrib/php',
+                         'test/distrib/python',
+                         'test/distrib/ruby']
+				   
+ends_with_whitelist = ['README.md',
+                       'LICENSE']
+
+# Triggers for core tests
+core_starts_with_triggers = ['test/core']
+
+# Triggers for c++ tests
+cpp_starts_with_triggers = ['src/cpp',
+                            'test/cpp',
+                            'test/distrib/cpp']
+
+# Triggers for c# tests
+csharp_starts_with_triggers = ['src/csharp',
+                               'test/distrib/csharp']
+
+# Triggers for node tests
+node_starts_with_triggers = ['src/node',
+                             'test/distrib/node']
+
+# Triggers for objective-c tests
+objc_starts_with_triggers = ['src/objective-c']
+
+# Triggers for php tests
+php_starts_with_triggers = ['src/php',
+                            'test/distrib/php']
+
+# Triggers for python tests
+python_starts_with_triggers = ['src/python',
+                               'test/distrib/python']
+
+# Triggers for ruby tests
+ruby_starts_with_triggers = ['src/ruby',
+                            'test/distrib/ruby']
+
+
+def _filter_whitelist(whitelist, triggers):
+  """
+  Removes triggers from whitelist
+  :param whitelist: list to remove values from
+  :param triggers: list of values to remove from whitelist
+  :return: filtered whitelist
+  """
+  filtered_whitelist = list(whitelist)
+  for trigger in triggers:
+    if trigger in filtered_whitelist:
+      filtered_whitelist.remove(trigger)
+    else:
+      """
+      If the trigger is not found in the whitelist, then there is likely
+      a mistake in the whitelist or trigger list, which needs to be addressed
+      to not wrongly skip tests
+      """
+      print("ERROR: '%s' trigger not in whitelist. Please fix this!" % trigger)
+  return filtered_whitelist
 
 
 def _get_changed_files():
   """
-  Get list of changed files between current branch and gRPC master branch
+  Get list of changed files between current branch and base of target merge branch
   """
   # git fetch might need to be called on Jenkins slave
   # todo(mattkwong): remove or uncomment below after seeing if Jenkins needs this
   # call(['git', 'fetch'])
   # this also collects files that are changed in the repo but not updated in the branch
-  return check_output(["git", "diff", "--name-only", "..origin/master"]).split()
+  # todo(mattkwong): change this to only collect changes files compared to base and not hardcode branch
+  return check_output(["git", "diff", "--name-only", "..origin/master"]).splitlines()
 
 
-def _can_skip_tests(file_names, starts_with_triggers=(), ends_with_triggers=()):
+def _can_skip_tests(file_names, starts_with_whitelist=[], ends_with_whitelist=[]):
   """
   Determines if tests are skippable based on if all file names do not match
   any begin or end triggers
@@ -59,9 +131,13 @@
   :param ends_with_triggers: tuple of strings to match with end of file names
   :return: safe to skip tests
   """
+  # convert lists to tuple to pass into str.startswith() and str.endswith()
+  starts_with_whitelist = tuple(starts_with_whitelist)
+  ends_with_whitelist = tuple(ends_with_whitelist)
+  print (starts_with_whitelist)
   for file_name in file_names:
-    if starts_with_triggers and file_name.startswith(starts_with_triggers) or \
-       ends_with_triggers and file_name.endswith(ends_with_triggers):
+    if starts_with_whitelist and not file_name.startswith(starts_with_whitelist) and \
+       ends_with_whitelist and not file_name.endswith(ends_with_whitelist):
          return False
   return True
 
@@ -73,6 +149,7 @@
   :param tag: string representing language or config to filter - "_(language)_" or "_(config)"
   :return: list of relevant tests
   """
+  # todo(mattkwong): find a more reliable way to filter tests - don't use shortname
   return [test for test in tests if not tag in test.shortname]
 
 
@@ -86,10 +163,69 @@
   changed_files = _get_changed_files()
   for changed_file in changed_files:
     print(changed_file)
-  # C++, tsan, msan, and asan have the same filter
-  if _can_skip_tests(changed_files, starts_with_triggers=run_cpp_starts_with_triggers):
-    tests = _remove_irrelevant_tests(tests, '_c++_') # filter out c++ tests
-    tests = _remove_irrelevant_tests(tests, '_tsan') # filter out tsan tests
-    tests = _remove_irrelevant_tests(tests, '_msan') # filter out msan tests
-    tests = _remove_irrelevant_tests(tests, '_asan') # filter out asan tests
+
+  changed_files = ['src/ruby/dgf']
+
+  # Filter core tests
+  skip_core = _can_skip_tests(changed_files,
+                              starts_with_whitelist=_filter_whitelist(starts_with_whitelist, core_starts_with_triggers),
+                              ends_with_whitelist=ends_with_whitelist)
+  if skip_core:
+    tests = _remove_irrelevant_tests(tests, '_c_')
+
+  # Filter c++ tests
+  skip_cpp = _can_skip_tests(changed_files,
+                             starts_with_whitelist=_filter_whitelist(starts_with_whitelist, cpp_starts_with_triggers),
+                             ends_with_whitelist=ends_with_whitelist)
+  if skip_cpp:
+    tests = _remove_irrelevant_tests(tests, '_cpp_')
+
+  # Tsan, msan, and asan tests skipped if core and c++ are skipped
+  if skip_core and skip_cpp:
+    tests = _remove_irrelevant_tests(tests, '_tsan')
+    tests = _remove_irrelevant_tests(tests, '_msan')
+    tests = _remove_irrelevant_tests(tests, '_asan')
+
+  # Filter c# tests
+  skip_csharp = _can_skip_tests(changed_files,
+                                starts_with_whitelist=_filter_whitelist(starts_with_whitelist, csharp_starts_with_triggers),
+                                ends_with_whitelist=ends_with_whitelist)
+  if skip_csharp:
+    tests = _remove_irrelevant_tests(tests, '_csharp_')
+
+  # Filter node tests
+  skip_node = _can_skip_tests(changed_files,
+                              starts_with_whitelist=_filter_whitelist(starts_with_whitelist, node_starts_with_triggers),
+                              ends_with_whitelist=ends_with_whitelist)
+  if skip_node:
+    tests = _remove_irrelevant_tests(tests, '_node_')
+
+  # Filter objc tests
+  skip_objc = _can_skip_tests(changed_files,
+                              starts_with_whitelist=_filter_whitelist(starts_with_whitelist, objc_starts_with_triggers),
+                              ends_with_whitelist=ends_with_whitelist)
+  if skip_objc:
+    tests = _remove_irrelevant_tests(tests, '_objc_')
+
+  # Filter php tests
+  skip_php = _can_skip_tests(changed_files,
+                             starts_with_whitelist=_filter_whitelist(starts_with_whitelist, php_starts_with_triggers),
+                             ends_with_whitelist=ends_with_whitelist)
+  if skip_php:
+    tests = _remove_irrelevant_tests(tests, '_php_')
+
+  # Filter python tests
+  skip_python = _can_skip_tests(changed_files,
+                                starts_with_whitelist=_filter_whitelist(starts_with_whitelist, python_starts_with_triggers),
+                                ends_with_whitelist=ends_with_whitelist)
+  if skip_python:
+    tests = _remove_irrelevant_tests(tests, '_python_')
+
+  # Filter ruby tests
+  skip_ruby = _can_skip_tests(changed_files,
+                              starts_with_whitelist=_filter_whitelist(starts_with_whitelist, ruby_starts_with_triggers),
+                              ends_with_whitelist=ends_with_whitelist)
+  if skip_ruby:
+    tests = _remove_irrelevant_tests(tests, '_ruby_')
+
   return tests