Update from https://crrev.com/312398

Involves adding many //testing/test.gni imports, fixing one
SkSurface::NewRenderTarget invocation inside sky, and fixing up
base::Process usage in the shell.

Review URL: https://codereview.chromium.org/862133002
diff --git a/testing/android/java/AndroidManifest.xml b/testing/android/java/AndroidManifest.xml
index 93dd71b..8cc36b2 100644
--- a/testing/android/java/AndroidManifest.xml
+++ b/testing/android/java/AndroidManifest.xml
@@ -12,6 +12,13 @@
 
     <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
 
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.WAKE_LOCK"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
     <application android:label="ChromeNativeTests"
             android:name="org.chromium.base.BaseChromiumApplication">
         <activity android:name=".ChromeNativeTestActivity"
@@ -28,11 +35,4 @@
             android:targetPackage="org.chromium.native_test"
             android:label="Instrumentation entry point for org.chromium.native_test"/>
 
-    <uses-permission android:name="android.permission.CAMERA" />
-    <uses-permission android:name="android.permission.INTERNET"/>
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
-    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
-    <uses-permission android:name="android.permission.WAKE_LOCK"/>
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
 </manifest>
diff --git a/testing/android/java/src/org/chromium/native_test/ChromeNativeTestActivity.java b/testing/android/java/src/org/chromium/native_test/ChromeNativeTestActivity.java
index 42befe5..d476cbc 100644
--- a/testing/android/java/src/org/chromium/native_test/ChromeNativeTestActivity.java
+++ b/testing/android/java/src/org/chromium/native_test/ChromeNativeTestActivity.java
@@ -7,6 +7,7 @@
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.Handler;
 import android.util.Log;
 
@@ -16,6 +17,8 @@
 import org.chromium.base.ResourceExtractor;
 import org.chromium.base.library_loader.NativeLibraries;
 
+import java.io.File;
+
 /**
  *  Android's NativeActivity is mostly useful for pure-native code.
  *  Our tests need to go up to our own java classes, which is not possible using
@@ -75,7 +78,16 @@
         if (commandLineFlags == null) commandLineFlags = "";
 
         String commandLineFilePath = getIntent().getStringExtra(EXTRA_COMMAND_LINE_FILE);
-        if (commandLineFilePath == null) commandLineFilePath = "";
+        if (commandLineFilePath == null) {
+            commandLineFilePath = "";
+        } else {
+            File commandLineFile = new File(commandLineFilePath);
+            if (!commandLineFile.isAbsolute()) {
+                commandLineFilePath = Environment.getExternalStorageDirectory() + "/"
+                        + commandLineFilePath;
+            }
+            Log.i(TAG, "command line file path: " + commandLineFilePath);
+        }
 
         // This directory is used by build/android/pylib/test_package_apk.py.
         nativeRunTests(commandLineFlags, commandLineFilePath, getFilesDir().getAbsolutePath(),
diff --git a/testing/android/java/src/org/chromium/native_test/ChromeNativeTestInstrumentationTestRunner.java b/testing/android/java/src/org/chromium/native_test/ChromeNativeTestInstrumentationTestRunner.java
index a5cf485..43135cc 100644
--- a/testing/android/java/src/org/chromium/native_test/ChromeNativeTestInstrumentationTestRunner.java
+++ b/testing/android/java/src/org/chromium/native_test/ChromeNativeTestInstrumentationTestRunner.java
@@ -27,9 +27,13 @@
  *  An Instrumentation that runs tests based on ChromeNativeTestActivity.
  */
 public class ChromeNativeTestInstrumentationTestRunner extends Instrumentation {
+    // TODO(jbudorick): Remove this extra when b/18981674 is fixed.
+    public static final String EXTRA_ONLY_OUTPUT_FAILURES =
+            "org.chromium.native_test.ChromeNativeTestInstrumentationTestRunner."
+                    + "OnlyOutputFailures";
 
     private static final String TAG = "ChromeNativeTestInstrumentationTestRunner";
-    private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*) *\\] ?([^ ]*) .*");
+    private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*) *\\] ?([^ ]+) .*");
 
     private static interface ResultsBundleGenerator {
         public Bundle generate(Map<String, TestResult> rawResults);
@@ -39,6 +43,7 @@
     private String mCommandLineFlags;
     private Bundle mLogBundle;
     private ResultsBundleGenerator mBundleGenerator;
+    private boolean mOnlyOutputFailures;
 
     @Override
     public void onCreate(Bundle arguments) {
@@ -46,6 +51,7 @@
         mCommandLineFlags = arguments.getString(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FLAGS);
         mLogBundle = new Bundle();
         mBundleGenerator = new RobotiumBundleGenerator();
+        mOnlyOutputFailures = arguments.containsKey(EXTRA_ONLY_OUTPUT_FAILURES);
         start();
     }
 
@@ -117,17 +123,27 @@
             for (String l = r.readLine(); l != null && !l.equals("<<ScopedMainEntryLogger");
                     l = r.readLine()) {
                 Matcher m = RE_TEST_OUTPUT.matcher(l);
+                boolean isFailure = false;
                 if (m.matches()) {
                     if (m.group(1).equals("RUN")) {
                         results.put(m.group(2), TestResult.UNKNOWN);
                     } else if (m.group(1).equals("FAILED")) {
                         results.put(m.group(2), TestResult.FAILED);
+                        isFailure = true;
+                        mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, l + "\n");
+                        sendStatus(0, mLogBundle);
                     } else if (m.group(1).equals("OK")) {
                         results.put(m.group(2), TestResult.PASSED);
                     }
                 }
-                mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, l + "\n");
-                sendStatus(0, mLogBundle);
+
+                // TODO(jbudorick): mOnlyOutputFailures is a workaround for b/18981674. Remove it
+                // once that issue is fixed.
+                if (!mOnlyOutputFailures || isFailure) {
+                    mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, l + "\n");
+                    sendStatus(0, mLogBundle);
+                }
+                Log.i(TAG, l);
             }
         } catch (InterruptedException e) {
             Log.e(TAG, "Interrupted while waiting for FIFO file creation: " + e.toString());
@@ -168,6 +184,9 @@
                         ++testsPassed;
                         break;
                     case FAILED:
+                        // TODO(jbudorick): Remove this log message once AMP execution and
+                        // results handling has been stabilized.
+                        Log.d(TAG, "FAILED: " + entry.getKey());
                         ++testsFailed;
                         break;
                     default:
@@ -178,11 +197,12 @@
             }
 
             StringBuilder resultBuilder = new StringBuilder();
-            resultBuilder.append("\nOK (" + Integer.toString(testsPassed) + " tests)");
             if (testsFailed > 0) {
                 resultBuilder.append(
                         "\nFAILURES!!! Tests run: " + Integer.toString(rawResults.size())
                         + ", Failures: " + Integer.toString(testsFailed) + ", Errors: 0");
+            } else {
+                resultBuilder.append("\nOK (" + Integer.toString(testsPassed) + " tests)");
             }
             resultsBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
                     resultBuilder.toString());
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 3e0535e..7d2f975 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -86,7 +86,6 @@
       },
       "sql_unittests",
       "nacl_loader_unittests",
-      "athena_unittests",
       "app_shell_browsertests",
       "app_shell_unittests",
       "chromevox_tests",
@@ -100,7 +99,6 @@
       "app_shell_browsertests",
       "app_shell_unittests",
       "ash_unittests",
-      "athena_unittests",
       "aura_unittests",
       "base_unittests",
       "cacheinvalidation_unittests",
@@ -250,7 +248,6 @@
           "shards": 2
         }
       },
-      "athena_unittests",
       "gcm_unit_tests",
       "skia_unittests",
       {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 68fb55b..4da8bc0 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -333,33 +333,20 @@
       }
     ]
   },
-  "Linux ChromiumOS Athena Tests (1)": {
-    "gtest_tests": [
-      {
-        "test": "athena_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        }
-      },
-      {
-        "test": "browser_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "shards": 5
-        }
-      }
-    ]
-  },
   "Site Isolation Linux": {
     "gtest_tests": [
       { "test": "content_unittests", "args": ["--site-per-process"] },
-      { "test": "content_browsertests", "args": ["--site-per-process", "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.SupportCrossProcessPostMessage:*.DontSwapProcessWithOnlyTargetBlank:*.DisownOpener:*.NavigateWithLeftoverFrames:*.DontPreemptNavigationWithFrameTreeUpdate:*.ProcessExitWithSwappedOutViews:*.SupportCrossProcessPostMessageWithMessagePort:*.AllowTargetedNavigationsInOpenerAfterSwap"] }
+      { "test": "content_browsertests", "args": ["--site-per-process", "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.SupportCrossProcessPostMessage:*.DisownOpener:*.DontPreemptNavigationWithFrameTreeUpdate:*.ProcessExitWithSwappedOutViews:*.SupportCrossProcessPostMessageWithMessagePort"] },
+      { "test": "unit_tests", "args": ["--site-per-process"] },
+      { "test": "browser_tests", "args": ["--site-per-process", "--gtest_filter=-AppApiTest.*:AutofillDialogControllerTest.*:BlockedAppApiTest.*:BookmarkOverrideTest.*:BrowserTest.OtherRedirectsDontForkProcess:ChromeAppAPITest.*:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExecuteScriptApiTest.ExecuteScriptPermissions:ExtensionApiTest.ContentScriptExtensionIframe:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionBrowserTest.LoadChromeExtensionsWithOptionsParamWhenEmbedded:ExtensionCrxInstallerTest.InstallDelayedUntilNextUpdate:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionSettingsApiTest.SimpleTest:ExtensionWebUITest.CanEmbedExtensionOptions:ExtensionWebUITest.ReceivesExtensionOptionsOnClose:ExternallyConnectableMessagingTest.*:GeolocationBrowserTest.*:HistoryBrowserTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:NaClBrowserTestNonSfiMode.*:OptionsUIBrowserTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PlatformAppUrlRedirectorBrowserTest.*:PopupBlockerBrowserTest.*:PortForwardingTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:ProfileManagerBrowserTest.*:RedirectTest.*:ReferrerPolicyTest.*:SandboxStatusUITest.*:SSLUITest.*:SyncFileSystemApiTest.GetFileStatuses:SyncFileSystemTest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.*:ZoomControllerBrowserTest.*"] }
     ]
   },
   "Site Isolation Win": {
     "gtest_tests": [
       { "test": "content_unittests", "args": ["--site-per-process"] },
-      { "test": "content_browsertests", "args": ["--site-per-process", "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.SupportCrossProcessPostMessage:*.DontSwapProcessWithOnlyTargetBlank:*.DisownOpener:*.NavigateWithLeftoverFrames:*.DontPreemptNavigationWithFrameTreeUpdate:*.ProcessExitWithSwappedOutViews:*.SupportCrossProcessPostMessageWithMessagePort:*.AllowTargetedNavigationsInOpenerAfterSwap"] }
+      { "test": "content_browsertests", "args": ["--site-per-process", "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.SupportCrossProcessPostMessage:*.DisownOpener:*.DontPreemptNavigationWithFrameTreeUpdate:*.ProcessExitWithSwappedOutViews:*.SupportCrossProcessPostMessageWithMessagePort"] },
+      { "test": "unit_tests", "args": ["--site-per-process"] },
+      { "test": "browser_tests", "args": ["--site-per-process", "--gtest_filter=-AppApiTest.*:AutofillDialogControllerTest.*:BlockedAppApiTest.*:BookmarkOverrideTest.*:BrowserTest.OtherRedirectsDontForkProcess:ChromeAppAPITest.*:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExecuteScriptApiTest.ExecuteScriptPermissions:ExtensionApiTest.ContentScriptExtensionIframe:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionBrowserTest.LoadChromeExtensionsWithOptionsParamWhenEmbedded:ExtensionCrxInstallerTest.InstallDelayedUntilNextUpdate:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionSettingsApiTest.SimpleTest:ExtensionWebUITest.CanEmbedExtensionOptions:ExtensionWebUITest.ReceivesExtensionOptionsOnClose:ExternallyConnectableMessagingTest.*:GeolocationBrowserTest.*:HistoryBrowserTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:NaClBrowserTestNonSfiMode.*:OptionsUIBrowserTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PlatformAppUrlRedirectorBrowserTest.*:PopupBlockerBrowserTest.*:PortForwardingTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:ProfileManagerBrowserTest.*:RedirectTest.*:ReferrerPolicyTest.*:SandboxStatusUITest.*:SSLUITest.*:SyncFileSystemApiTest.GetFileStatuses:SyncFileSystemTest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.*:ZoomControllerBrowserTest.*"] }
     ]
   },
   "Browser Side Navigation Linux": {
@@ -367,5 +354,50 @@
       { "test": "content_unittests", "args": ["--enable-browser-side-navigation", "--gtest_filter=-ResourceDispatcherHostTest.TransferNavigationHtml:ResourceDispatcherHostTest.TransferNavigationText:ResourceDispatcherHostTest.TransferNavigationWithProcessCrash:ResourceDispatcherHostTest.TransferNavigationWithTwoRedirects:ResourceDispatcherHostTest.TransferTwoNavigationsHtml:RenderFrameHostManagerTest.CancelPendingProperlyDeletesOrSwaps:WebContentsImplTest.CrossSiteNotPreemptedDuringBeforeUnload"] },
       { "test": "content_browsertests", "args": ["--enable-browser-side-navigation"] }
     ]
+  },
+  "CrWinClang tester": {
+    "gtest_tests": [
+      {
+        "test": "base_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
+      "cacheinvalidation_unittests",
+      "chrome_elf_unittests",
+      "components_unittests",
+      "courgette_unittests",
+      "crypto_unittests",
+      "extensions_unittests",
+      "gcm_unit_tests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "url_unittests",
+      "jingle_unittests",
+      "content_unittests",
+      "device_unittests",
+      "media_unittests",
+      "net_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "remoting_unittests",
+      "sbox_unittests",
+      "sbox_integration_tests",
+      "sbox_validation_tests",
+      "ipc_tests",
+      "sync_unit_tests",
+      "unit_tests",
+      "sql_unittests",
+      "ui_base_unittests",
+      "views_unittests",
+      "browser_tests",
+      {
+        "test": "content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
+      "installer_util_unittests"
+    ]
   }
 }
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 3c05ad7..7c71066 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -33,7 +33,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -66,7 +71,12 @@
         }
       },
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "interactive_ui_tests",
         "swarming": {
@@ -76,7 +86,12 @@
       "ipc_mojo_unittests",
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
@@ -127,6 +142,18 @@
     ],
     "scripts": [
       {
+        "name": "checkdeps",
+        "script": "checkdeps.py"
+      },
+      {
+        "name": "checklicenses",
+        "script": "checklicenses.py"
+      },
+      {
+        "name": "checkperms",
+        "script": "checkperms.py"
+      },
+      {
         "name": "telemetry_unittests",
         "script": "telemetry_unittests.py"
       },
@@ -174,7 +201,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -207,7 +239,12 @@
         }
       },
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "interactive_ui_tests",
         "swarming": {
@@ -217,7 +254,12 @@
       "ipc_mojo_unittests",
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
@@ -307,7 +349,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -340,7 +387,12 @@
         }
       },
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "interactive_ui_tests",
         "swarming": {
@@ -351,7 +403,12 @@
       "ipc_mojo_unittests",
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index cfc0a2a..8f8a30e 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -30,7 +30,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "content_browsertests",
         "swarming": {
@@ -52,7 +57,12 @@
           "can_use_on_swarming_builders": true
         }
       },
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "google_apis_unittests",
       {
         "test": "interactive_ui_tests",
@@ -62,7 +72,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "message_center_unittests",
         "swarming": {
@@ -154,7 +169,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "content_browsertests",
         "swarming": {
@@ -176,7 +196,12 @@
           "can_use_on_swarming_builders": true
         }
       },
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "google_apis_unittests",
       {
         "test": "interactive_ui_tests",
@@ -186,7 +211,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "message_center_unittests",
         "swarming": {
@@ -278,7 +308,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "content_browsertests",
         "swarming": {
@@ -300,7 +335,12 @@
           "can_use_on_swarming_builders": true
         }
       },
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "google_apis_unittests",
       {
         "test": "interactive_ui_tests",
@@ -310,7 +350,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "message_center_unittests",
         "swarming": {
@@ -402,7 +447,12 @@
       "cast_unittests",
       "cc_unittests",
       "chromedriver_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "content_browsertests",
         "swarming": {
@@ -424,7 +474,12 @@
           "can_use_on_swarming_builders": true
         }
       },
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "google_apis_unittests",
       {
         "test": "interactive_ui_tests",
@@ -435,7 +490,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "message_center_unittests",
         "swarming": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 296c0a7..168f3a3 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -233,7 +233,6 @@
           "can_use_on_swarming_builders": true
         }
       },
-      "athena_unittests",
       "aura_unittests",
       {
         "test": "base_unittests",
diff --git a/testing/buildbot/chromium.webkit.json b/testing/buildbot/chromium.webkit.json
index 47f4c49..475f4ec 100644
--- a/testing/buildbot/chromium.webkit.json
+++ b/testing/buildbot/chromium.webkit.json
@@ -83,7 +83,6 @@
       },
       "sql_unittests",
       "nacl_loader_unittests",
-      "athena_unittests",
       "app_shell_browsertests",
       "app_shell_unittests",
       "chromevox_tests",
@@ -173,7 +172,6 @@
           "shards": 2
         }
       },
-      "athena_unittests",
       "gcm_unit_tests",
       "skia_unittests",
       {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index a138a36..a257144 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -23,7 +23,12 @@
       "cc_unittests",
       "chromedriver_unittests",
       "chrome_elf_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -44,7 +49,12 @@
       "gcm_unit_tests",
       "gfx_unittests",
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "installer_util_unittests",
       {
         "test": "interactive_ui_tests",
@@ -55,7 +65,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       {
         "test": "net_unittests",
         "swarming": {
@@ -128,7 +143,12 @@
       "cc_unittests",
       "chromedriver_unittests",
       "chrome_elf_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -149,7 +169,12 @@
       "gcm_unit_tests",
       "gfx_unittests",
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "installer_util_unittests",
       {
         "test": "interactive_ui_tests",
@@ -160,7 +185,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
@@ -244,7 +274,12 @@
       "chromedriver_unittests",
       "chrome_elf_unittests",
       "components_browsertests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -266,7 +301,12 @@
       "gcm_unit_tests",
       "gfx_unittests",
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "installer_util_unittests",
       {
         "test": "interactive_ui_tests",
@@ -278,7 +318,12 @@
       "ipc_tests",
       "jingle_unittests",
       "keyboard_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "message_center_unittests",
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
@@ -367,7 +412,12 @@
       "chromedriver_unittests",
       "chrome_elf_unittests",
       "components_browsertests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -389,7 +439,12 @@
       "gcm_unit_tests",
       "gfx_unittests",
       "google_apis_unittests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "installer_util_unittests",
       {
         "test": "interactive_ui_tests",
@@ -401,7 +456,12 @@
       "ipc_tests",
       "jingle_unittests",
       "keyboard_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "message_center_unittests",
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
@@ -487,7 +547,12 @@
       "cc_unittests",
       "chromedriver_unittests",
       "chrome_elf_unittests",
-      "components_unittests",
+      {
+        "test": "components_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "compositor_unittests",
       {
         "test": "content_browsertests",
@@ -507,7 +572,12 @@
       "events_unittests",
       "extensions_unittests",
       "gcm_unit_tests",
-      "gpu_unittests",
+      {
+        "test": "gpu_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "installer_util_unittests",
       {
         "test": "interactive_ui_tests",
@@ -518,7 +588,12 @@
       },
       "ipc_tests",
       "jingle_unittests",
-      "media_unittests",
+      {
+        "test": "media_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
diff --git a/testing/buildbot/chromium_athena.json b/testing/buildbot/chromium_athena.json
deleted file mode 100644
index 7b9d3c6..0000000
--- a/testing/buildbot/chromium_athena.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "compile_targets": [
-    "chrome",
-    "athena_main"
-  ],
-  "gtest_tests": [
-    {
-      "test": "browser_tests",
-      "swarming": {
-        "can_use_on_swarming_builders": true,
-        "shards": 5
-      }
-    },
-    {
-      "test": "athena_unittests",
-      "swarming": {
-        "can_use_on_swarming_builders": true,
-        "shards": 5
-      }
-    }
-  ]
-}
diff --git a/testing/buildbot/chromium_memory_trybot.json b/testing/buildbot/chromium_memory_trybot.json
index 2b8564e..af0f169 100644
--- a/testing/buildbot/chromium_memory_trybot.json
+++ b/testing/buildbot/chromium_memory_trybot.json
@@ -16,7 +16,12 @@
     },
     "cacheinvalidation_unittests",
     "cc_unittests",
-    "components_unittests",
+    {
+      "test": "components_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true
+      }
+    },
     {
       "test": "content_browsertests",
       "swarming": {
@@ -39,7 +44,12 @@
     "gcm_unit_tests",
     "gfx_unittests",
     "google_apis_unittests",
-    "gpu_unittests",
+    {
+      "test": "gpu_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true
+      }
+    },
     {
       "test": "interactive_ui_tests",
       "swarming": {
@@ -49,11 +59,17 @@
     },
     "ipc_tests",
     "jingle_unittests",
-    "media_unittests",
+    {
+      "test": "media_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true
+      }
+    },
     {
       "test": "net_unittests",
       "swarming": {
-        "can_use_on_swarming_builders": true
+        "can_use_on_swarming_builders": true,
+        "shards": 2
       }
     },
     "ppapi_unittests",
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
index cdf0ea1..eef2619 100644
--- a/testing/buildbot/chromium_trybot.json
+++ b/testing/buildbot/chromium_trybot.json
@@ -67,7 +67,12 @@
       "platforms": ["win"]
     },
     "components_browsertests",
-    "components_unittests",
+    {
+      "test": "components_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true
+      }
+    },
     {
       "test": "compositor_unittests",
       "platforms": ["linux", "win"]
@@ -112,7 +117,12 @@
       }
     },
     "google_apis_unittests",
-    "gpu_unittests",
+    {
+      "test": "gpu_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true
+      }
+    },
     {
       "test": "interactive_ui_tests",
       "swarming": {
@@ -135,7 +145,12 @@
       "platforms": ["linux", "win"]
     },
     "media_perftests",
-    "media_unittests",
+    {
+      "test": "media_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true
+      }
+    },
     {
       "test": "message_center_unittests",
       "swarming": {
@@ -251,15 +266,6 @@
       ]
     },
     {
-      "test": "athena_unittests",
-      "platforms": ["linux"],
-      "chromium_configs": [
-        "chromium_chromeos",
-        "chromium_chromeos_athena",
-        "chromium_chromeos_ozone"
-      ]
-    },
-    {
       "test": "display_unittests",
       "platforms": ["linux"]
     },
diff --git a/testing/chromoting/browser_test_commands_linux.txt b/testing/chromoting/browser_test_commands_linux.txt
index 2f5f2be..d6f2bf5 100644
--- a/testing/chromoting/browser_test_commands_linux.txt
+++ b/testing/chromoting/browser_test_commands_linux.txt
@@ -3,4 +3,6 @@
 /usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=RemoteDesktopBrowserTest.MANUAL_Auth --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=gafyd
 /usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=RemoteDesktopBrowserTest.MANUAL_Auth --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=non-gmail
 /usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=RemoteDesktopBrowserTest.MANUAL_Launch --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp.v2 --extension-name=Chromoting
-/usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=Me2MeBrowserTest.MANUAL_Me2Me_Connect_Local_Host --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=gmail --me2me-pin=123456 --override-user-data-dir=/tmp/chromoting_test_profile
\ No newline at end of file
+/usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=Me2MeBrowserTest.MANUAL_Me2Me_Connect_Local_Host --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=gmail --me2me-pin=123456 --override-user-data-dir=/tmp/chromoting_test_profile
+/usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=It2MeBrowserTest.MANUAL_Connect --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=gmail --override-user-data-dir=/tmp/chromoting_test_profile
+/usr/bin/python ../xvfb.py #PROD_DIR# #PROD_DIR#/browser_tests --gtest_filter=It2MeBrowserTest.MANUAL_InvalidAccessCode --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=#PROD_DIR#/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=gmail --override-user-data-dir=/tmp/chromoting_test_profile
\ No newline at end of file
diff --git a/testing/chromoting/browser_tests_launcher.py b/testing/chromoting/browser_tests_launcher.py
index be66955..0cb903b 100644
--- a/testing/chromoting/browser_tests_launcher.py
+++ b/testing/chromoting/browser_tests_launcher.py
@@ -80,20 +80,14 @@
     shutil.rmtree(user_profile_dir)
 
 
-def InitialiseTestMachineForLinux(cfg_file, manifest_file, user_profile_dir):
+def InitialiseTestMachineForLinux(cfg_file):
   """Sets up a Linux machine for connect-to-host browser-tests.
 
-  Copy over me2me host-config and manifest files to expected locations.
+  Copy over me2me host-config to expected locations.
   By default, the Linux me2me host expects the host-config file to be under
   $HOME/.config/chrome-remote-desktop
   Its name is expected to have a hash that is specific to a machine.
 
-  When a user launches the remoting web-app, the native-message host process is
-  started. For this to work, the manifest file for me2me host is expected to be
-  in a specific folder under the user-profile dir.
-
-  This function performs both the above tasks.
-
   TODO(anandc):
   Once we have Linux machines in the swarming lab already installed with the
   me2me host, this function should also perform the step of starting the host.
@@ -102,8 +96,6 @@
 
   Args:
     cfg_file: location of test account's host-config file.
-    manifest_file: location of me2me host manifest file.
-    user_profile_dir: user-profile-dir to be used by the connect-to-host tests.
   """
 
   # First get home directory on current machine.
@@ -121,21 +113,39 @@
       config_file_src,
       os.path.join(default_config_file_location, default_config_file_name))
 
-  # Next, create a user-profile dir, and place the me2me manifest.json file in
-  # the expected location for native-messating-host to work properly.
+  # Finally, start chromoting host.
+  RunCommandInSubProcess(CHROMOTING_HOST_PATH + ' --start')
+
+
+def SetupUserProfileDir(me2me_manifest_file, it2me_manifest_file,
+                        user_profile_dir):
+  """Sets up the Google Chrome user profile directory
+
+  Delete the previous user profile directory if exists and create a new one.
+  This invalidates any state changes by the previous test so each test can start
+  with the same environment.
+
+  When a user launches the remoting web-app, the native messaging host process
+  is started. For this to work, this function places the me2me and it2me native
+  messaging host manifest files in a specific folder under the user-profile dir.
+
+  Args:
+    me2me_manifest_file: location of me2me native messaging host manifest file.
+    it2me_manifest_file: location of it2me native messaging host manifest file.
+    user_profile_dir: Chrome user-profile-directory.
+  """
   native_messaging_folder = os.path.join(user_profile_dir, NATIVE_MESSAGING_DIR)
 
   if os.path.exists(user_profile_dir):
     shutil.rmtree(user_profile_dir)
   os.makedirs(native_messaging_folder)
 
-  manifest_file_src = os.path.join(os.getcwd(), manifest_file)
-  manifest_file_dest = (
-      os.path.join(native_messaging_folder, os.path.basename(manifest_file)))
-  shutil.copyfile(manifest_file_src, manifest_file_dest)
-
-  # Finally, start chromoting host.
-  RunCommandInSubProcess(CHROMOTING_HOST_PATH + ' --start')
+  manifest_files = [me2me_manifest_file, it2me_manifest_file]
+  for manifest_file in manifest_files:
+    manifest_file_src = os.path.join(os.getcwd(), manifest_file)
+    manifest_file_dest = (
+        os.path.join(native_messaging_folder, os.path.basename(manifest_file)))
+    shutil.copyfile(manifest_file_src, manifest_file_dest)
 
 
 def main():
@@ -146,19 +156,24 @@
                       help='path to folder having product and test binaries.')
   parser.add_argument('-c', '--cfg_file',
                       help='path to test host config file.')
-  parser.add_argument('-m', '--manifest_file',
+  parser.add_argument('--me2me_manifest_file',
                       help='path to me2me host manifest file.')
+  parser.add_argument('--it2me_manifest_file',
+                      help='path to it2me host manifest file.')
   parser.add_argument(
       '-u', '--user_profile_dir',
       help='path to user-profile-dir, used by connect-to-host tests.')
 
   args = parser.parse_args()
 
-  InitialiseTestMachineForLinux(args.cfg_file, args.manifest_file,
-                                args.user_profile_dir)
+  InitialiseTestMachineForLinux(args.cfg_file)
 
   with open(args.commands_file) as f:
     for line in f:
+      # Reset the user profile directory to start each test with a clean slate.
+      SetupUserProfileDir(args.me2me_manifest_file, args.it2me_manifest_file,
+                          args.user_profile_dir)
+
       # Replace the PROD_DIR value in the command-line with
       # the passed in value.
       line = line.replace(PROD_DIR_ID, args.prod_dir)
diff --git a/testing/chromoting/chromoting_integration_tests.isolate b/testing/chromoting/chromoting_integration_tests.isolate
index 83eb440..be04bd6 100644
--- a/testing/chromoting/chromoting_integration_tests.isolate
+++ b/testing/chromoting/chromoting_integration_tests.isolate
@@ -13,8 +13,10 @@
           '<(PRODUCT_DIR)',
           '--cfg_file',
           '../../remoting/tools/internal/test-account-host-config.json',
-          '--manifest_file',
+          '--me2me_manifest_file',
           '<(PRODUCT_DIR)/remoting/com.google.chrome.remote_desktop.json',
+          '--it2me_manifest_file',
+          '<(PRODUCT_DIR)/remoting/com.google.chrome.remote_assistance.json',
           '--user_profile_dir',
           '/tmp/chromoting_test_profile',
         ],
@@ -27,6 +29,7 @@
           '<(PRODUCT_DIR)/nacl_irt_x86_64.nexe',
           '../../remoting/tools/internal/test-account-host-config.json',
           '<(PRODUCT_DIR)/remoting/com.google.chrome.remote_desktop.json',
+          '<(PRODUCT_DIR)/remoting/com.google.chrome.remote_assistance.json',
         ],
       },
     }],
@@ -44,6 +47,7 @@
           '<(PRODUCT_DIR)/browser_tests<(EXECUTABLE_SUFFIX)',
           '<(PRODUCT_DIR)/remoting/remoting.webapp/',
           '<(PRODUCT_DIR)/remoting/remoting.webapp.v2/',
+          '<(PRODUCT_DIR)/remoting/browser_test_resources/',
           '<(PRODUCT_DIR)/resources.pak',
           '../../remoting/tools/internal/test_accounts.json',
         ],
diff --git a/testing/commit_queue/config.json b/testing/commit_queue/config.json
index 3e39bf3..a3142a5 100644
--- a/testing/commit_queue/config.json
+++ b/testing/commit_queue/config.json
@@ -8,10 +8,10 @@
                         "linux_chromium_asan_rel_ng": ["defaulttests"]
                     },
                     "tryserver.chromium.mac": {
+                        "mac_chromium_gn_rel": ["defaulttests"]
                     },
                     "tryserver.chromium.win": {
-                        "win8_chromium_ng": ["defaulttests"],
-                        "win_chromium_compile_dbg_ng": ["defaulttests"]
+                        "win8_chromium_ng": ["defaulttests"]
                     }
                 }
             }
@@ -54,6 +54,7 @@
               "linux_chromium_asan_rel": ["defaulttests"],
               "linux_chromium_chromeos_compile_dbg_ng": ["defaulttests"],
               "linux_chromium_chromeos_rel_ng": ["defaulttests"],
+              "linux_chromium_gn_chromeos_rel": ["defaulttests"],
               "linux_chromium_gn_dbg": ["defaulttests"],
               "linux_chromium_gn_rel": ["defaulttests"],
               "linux_chromium_rel_ng": ["defaulttests"],
@@ -83,10 +84,11 @@
               "ios_rel_device_ninja_ng": ["defaulttests"]
             },
             "tryserver.chromium.win": {
-              "win_chromium_compile_dbg": ["defaulttests"],
+              "win8_chromium_rel": ["defaulttests"],
+              "win8_chromium_gn_rel": ["defaulttests"],
+              "win_chromium_compile_dbg_ng": ["defaulttests"],
               "win_chromium_rel_ng": ["defaulttests"],
-              "win_chromium_x64_rel_ng": ["defaulttests"],
-              "win8_chromium_rel": ["defaulttests"]
+              "win_chromium_x64_rel_ng": ["defaulttests"]
             },
             "tryserver.chromium.gpu": {
                 "linux_gpu": ["defaulttests"],
diff --git a/testing/scripts/checklicenses.py b/testing/scripts/checklicenses.py
new file mode 100755
index 0000000..43342d0
--- /dev/null
+++ b/testing/scripts/checklicenses.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import json
+import os
+import sys
+
+
+import common
+
+
+def main_run(args):
+  with common.temporary_file() as tempfile_path:
+    rc = common.run_command([
+        os.path.join(common.SRC_DIR, 'tools', 'checklicenses',
+                     'checklicenses.py'),
+        '--json', tempfile_path
+    ])
+
+    with open(tempfile_path) as f:
+      checklicenses_results = json.load(f)
+
+  result_set = set()
+  for result in checklicenses_results:
+    result_set.add((result['filename'], result['license']))
+
+  json.dump({
+      'valid': True,
+      'failures': ['%s: %s' % (r[0], r[1]) for r in result_set],
+  }, args.output)
+
+  return rc
+
+
+def main_compile_targets(args):
+  json.dump([], args.output)
+
+
+if __name__ == '__main__':
+  funcs = {
+    'run': main_run,
+    'compile_targets': main_compile_targets,
+  }
+  sys.exit(common.run_script(sys.argv[1:], funcs))
diff --git a/testing/scripts/checkperms.py b/testing/scripts/checkperms.py
new file mode 100755
index 0000000..17e32c4
--- /dev/null
+++ b/testing/scripts/checkperms.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import json
+import os
+import sys
+
+
+import common
+
+
+def main_run(args):
+  with common.temporary_file() as tempfile_path:
+    rc = common.run_command([
+        os.path.join(common.SRC_DIR, 'tools', 'checkperms', 'checkperms.py'),
+        '--root', args.paths['checkout'],
+        '--json', tempfile_path
+    ])
+
+    with open(tempfile_path) as f:
+      checkperms_results = json.load(f)
+
+  result_set = set()
+  for result in checkperms_results:
+    result_set.add((result['rel_path'], result['error']))
+
+  json.dump({
+      'valid': True,
+      'failures': ['%s: %s' % (r[0], r[1]) for r in result_set],
+  }, args.output)
+
+  return rc
+
+
+def main_compile_targets(args):
+  json.dump([], args.output)
+
+
+if __name__ == '__main__':
+  funcs = {
+    'run': main_run,
+    'compile_targets': main_compile_targets,
+  }
+  sys.exit(common.run_script(sys.argv[1:], funcs))
diff --git a/testing/test.gni b/testing/test.gni
index 50b23df..9362a78 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -1,3 +1,237 @@
 # Copyright 2015 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+
+# ==============================================================================
+# TEST SETUP
+# ==============================================================================
+
+# Define a test as an executable (or apk on Android) with the "testonly" flag
+# set.
+template("test") {
+  if (is_android) {
+    import("//build/config/android/config.gni")
+    import("//build/config/android/rules.gni")
+
+    main_target_name = target_name
+    library_name = "_${target_name}__library"
+    apk_name = "${target_name}_apk"
+
+    shared_library(library_name) {
+      # Configs will always be defined since we set_defaults for a component
+      # in the main config. We want to use those rather than whatever came with
+      # the nested shared/static library inside the component.
+      configs = []  # Prevent list overwriting warning.
+      configs = invoker.configs
+
+      # See above call.
+      set_sources_assignment_filter([])
+
+      testonly = true
+
+      if (defined(invoker.all_dependent_configs)) {
+        all_dependent_configs = invoker.all_dependent_configs
+      }
+      if (defined(invoker.allow_circular_includes_from)) {
+        allow_circular_includes_from = invoker.allow_circular_includes_from
+      }
+      if (defined(invoker.cflags)) {
+        cflags = invoker.cflags
+      }
+      if (defined(invoker.cflags_c)) {
+        cflags_c = invoker.cflags_c
+      }
+      if (defined(invoker.cflags_cc)) {
+        cflags_cc = invoker.cflags_cc
+      }
+      if (defined(invoker.cflags_objc)) {
+        cflags_objc = invoker.cflags_objc
+      }
+      if (defined(invoker.cflags_objcc)) {
+        cflags_objcc = invoker.cflags_objcc
+      }
+      if (defined(invoker.check_includes)) {
+        check_includes = invoker.check_includes
+      }
+      if (defined(invoker.data)) {
+        data = invoker.data
+      }
+      if (defined(invoker.data_deps)) {
+        data_deps = invoker.data_deps
+      }
+      if (defined(invoker.datadeps)) {
+        datadeps = invoker.datadeps
+      }
+      if (defined(invoker.defines)) {
+        defines = invoker.defines
+      }
+      deps = []
+      if (!defined(invoker.use_launcher) || invoker.use_launcher) {
+        deps += [ "//testing/android:native_test_native_code" ]
+      }
+      if (defined(invoker.deps)) {
+        deps += invoker.deps
+      }
+      if (defined(invoker.direct_dependent_configs)) {
+        direct_dependent_configs = invoker.direct_dependent_configs
+      }
+      if (defined(invoker.forward_dependent_configs_from)) {
+        forward_dependent_configs_from = invoker.forward_dependent_configs_from
+      }
+      if (defined(invoker.include_dirs)) {
+        include_dirs = invoker.include_dirs
+      }
+      if (defined(invoker.ldflags)) {
+        ldflags = invoker.ldflags
+      }
+      if (defined(invoker.lib_dirs)) {
+        lib_dirs = invoker.lib_dirs
+      }
+      if (defined(invoker.libs)) {
+        libs = invoker.libs
+      }
+      if (defined(invoker.output_extension)) {
+        output_extension = invoker.output_extension
+      }
+      if (defined(invoker.output_name)) {
+        output_name = invoker.output_name
+      }
+      if (defined(invoker.public)) {
+        public = invoker.public
+      }
+      if (defined(invoker.public_configs)) {
+        public_configs = invoker.public_configs
+      }
+      if (defined(invoker.public_deps)) {
+        public_deps = invoker.public_deps
+      }
+      if (defined(invoker.sources)) {
+        sources = invoker.sources
+      }
+      if (defined(invoker.visibility)) {
+        visibility = invoker.visibility
+      }
+    }
+
+    unittest_apk(apk_name) {
+      unittests_dep = ":$library_name"
+      apk_name = main_target_name
+      if (defined(invoker.output_name)) {
+        test_output_name = invoker.output_name
+        unittests_binary = "lib${test_output_name}.so"
+      }
+      deps = [
+        ":$library_name",
+      ]
+      if (defined(invoker.apk_deps)) {
+        deps += invoker.apk_deps
+      }
+    }
+
+    group(target_name) {
+      testonly = true
+
+      deps = [
+        ":$library_name",
+        ":$apk_name",
+      ]
+    }
+  } else {
+    executable(target_name) {
+      # See above.
+      configs = []  # Prevent list overwriting warning.
+      configs = invoker.configs
+
+      # See above call.
+      set_sources_assignment_filter([])
+
+      testonly = true
+
+      if (defined(invoker.all_dependent_configs)) {
+        all_dependent_configs = invoker.all_dependent_configs
+      }
+      if (defined(invoker.allow_circular_includes_from)) {
+        allow_circular_includes_from = invoker.allow_circular_includes_from
+      }
+      if (defined(invoker.cflags)) {
+        cflags = invoker.cflags
+      }
+      if (defined(invoker.cflags_c)) {
+        cflags_c = invoker.cflags_c
+      }
+      if (defined(invoker.cflags_cc)) {
+        cflags_cc = invoker.cflags_cc
+      }
+      if (defined(invoker.cflags_objc)) {
+        cflags_objc = invoker.cflags_objc
+      }
+      if (defined(invoker.cflags_objcc)) {
+        cflags_objcc = invoker.cflags_objcc
+      }
+      if (defined(invoker.check_includes)) {
+        check_includes = invoker.check_includes
+      }
+      if (defined(invoker.data)) {
+        data = invoker.data
+      }
+      if (defined(invoker.data_deps)) {
+        data_deps = invoker.data_deps
+      }
+      if (defined(invoker.datadeps)) {
+        datadeps = invoker.datadeps
+      }
+      if (defined(invoker.defines)) {
+        defines = invoker.defines
+      }
+
+      # All shared libraries must have the sanitizer deps to properly link in
+      # asan mode (this target will be empty in other cases).
+      if (defined(invoker.deps)) {
+        deps = invoker.deps + [ "//build/config/sanitizers:deps" ]
+      } else {
+        deps = [
+          "//build/config/sanitizers:deps",
+        ]
+      }
+      if (defined(invoker.direct_dependent_configs)) {
+        direct_dependent_configs = invoker.direct_dependent_configs
+      }
+      if (defined(invoker.forward_dependent_configs_from)) {
+        forward_dependent_configs_from = invoker.forward_dependent_configs_from
+      }
+      if (defined(invoker.include_dirs)) {
+        include_dirs = invoker.include_dirs
+      }
+      if (defined(invoker.ldflags)) {
+        ldflags = invoker.ldflags
+      }
+      if (defined(invoker.lib_dirs)) {
+        lib_dirs = invoker.lib_dirs
+      }
+      if (defined(invoker.libs)) {
+        libs = invoker.libs
+      }
+      if (defined(invoker.output_extension)) {
+        output_extension = invoker.output_extension
+      }
+      if (defined(invoker.output_name)) {
+        output_name = invoker.output_name
+      }
+      if (defined(invoker.public)) {
+        public = invoker.public
+      }
+      if (defined(invoker.public_configs)) {
+        public_configs = invoker.public_configs
+      }
+      if (defined(invoker.public_deps)) {
+        public_deps = invoker.public_deps
+      }
+      if (defined(invoker.sources)) {
+        sources = invoker.sources
+      }
+      if (defined(invoker.visibility)) {
+        visibility = invoker.visibility
+      }
+    }
+  }
+}