Clone of chromium aad1ce808763f59c7a3753e08f1500a104ecc6fd refs/remotes/origin/HEAD
diff --git a/testing/OWNERS b/testing/OWNERS
new file mode 100644
index 0000000..72e8ffc
--- /dev/null
+++ b/testing/OWNERS
@@ -0,0 +1 @@
+*
diff --git a/testing/PRESUBMIT.py b/testing/PRESUBMIT.py
new file mode 100644
index 0000000..90e524f
--- /dev/null
+++ b/testing/PRESUBMIT.py
@@ -0,0 +1,25 @@
+# Copyright (c) 2012 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.
+
+"""Top-level presubmit script for testing.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
+details on the presubmit API built into gcl.
+"""
+
+
+def CommonChecks(input_api, output_api):
+ output = []
+ blacklist = [r'gmock.*', r'gtest.*']
+ output.extend(input_api.canned_checks.RunPylint(
+ input_api, output_api, black_list=blacklist))
+ return output
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return CommonChecks(input_api, output_api)
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return CommonChecks(input_api, output_api)
diff --git a/testing/android/BUILD.gn b/testing/android/BUILD.gn
new file mode 100644
index 0000000..c26830c
--- /dev/null
+++ b/testing/android/BUILD.gn
@@ -0,0 +1,40 @@
+# Copyright 2014 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("//build/config/android/rules.gni")
+
+# GYP: //testing/android/native_test.gyp:native_test_native_code
+source_set("native_test_native_code") {
+ testonly = true
+ sources = [
+ "native_test_launcher.cc"
+ ]
+ deps = [
+ ":native_test_jni_headers",
+ ":native_test_util",
+ "//base",
+ "//base/test:test_support",
+ "//base/third_party/dynamic_annotations",
+ "//testing/gtest",
+ ]
+}
+
+# GYP: //testing/android/native_test.gyp:native_test_jni_headers
+generate_jni("native_test_jni_headers") {
+ sources = [
+ "java/src/org/chromium/native_test/ChromeNativeTestActivity.java",
+ ]
+ jni_package = "testing"
+}
+
+# GYP: //testing/android/native_test.gyp:native_test_util
+source_set("native_test_util") {
+ sources = [
+ "native_test_util.cc",
+ "native_test_util.h",
+ ]
+ deps = [
+ "//base"
+ ]
+}
diff --git a/testing/android/OWNERS b/testing/android/OWNERS
new file mode 100644
index 0000000..0242c2d
--- /dev/null
+++ b/testing/android/OWNERS
@@ -0,0 +1,7 @@
+aruslan@chromium.org
+dtrainor@chromium.org
+miguelg@chromium.org
+nyquist@chromium.org
+skyostil@chromium.org
+tedchoc@chromium.org
+yfriedman@chromium.org
diff --git a/testing/android/README.chromium b/testing/android/README.chromium
new file mode 100644
index 0000000..c00255a
--- /dev/null
+++ b/testing/android/README.chromium
@@ -0,0 +1,2 @@
+apk-based runner for Chromium unit test bundles. This is a simple wrapper APK
+that should include a single gtest native library.
diff --git a/testing/android/java/AndroidManifest.xml b/testing/android/java/AndroidManifest.xml
new file mode 100644
index 0000000..97d916b
--- /dev/null
+++ b/testing/android/java/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2014 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.chromium.native_test"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+
+ <application android:label="ChromeNativeTests"
+ android:name="org.chromium.base.BaseChromiumApplication">
+ <activity android:name=".ChromeNativeTestActivity"
+ android:label="ChromeNativeTest"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <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
new file mode 100644
index 0000000..4d4839c
--- /dev/null
+++ b/testing/android/java/src/org/chromium/native_test/ChromeNativeTestActivity.java
@@ -0,0 +1,86 @@
+// Copyright 2012 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.
+
+package org.chromium.native_test;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+import org.chromium.base.PathUtils;
+import org.chromium.base.PowerMonitor;
+import org.chromium.base.ResourceExtractor;
+import org.chromium.base.library_loader.NativeLibraries;
+
+/**
+ * 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
+ * the native activity class loader.
+ */
+public class ChromeNativeTestActivity extends Activity {
+ private static final String TAG = "ChromeNativeTestActivity";
+ private static final String EXTRA_RUN_IN_SUB_THREAD = "RunInSubThread";
+ // We post a delayed task to run tests so that we do not block onCreate().
+ private static final long RUN_TESTS_DELAY_IN_MS = 300;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Needed by path_utils_unittest.cc
+ PathUtils.setPrivateDataDirectorySuffix("chrome");
+
+ ResourceExtractor resourceExtractor = ResourceExtractor.get(getApplicationContext());
+ resourceExtractor.setExtractAllPaksForTesting();
+ resourceExtractor.startExtractingResources();
+ resourceExtractor.waitForCompletion();
+
+ // Needed by system_monitor_unittest.cc
+ PowerMonitor.createForTests(this);
+
+ loadLibraries();
+ Bundle extras = this.getIntent().getExtras();
+ if (extras != null && extras.containsKey(EXTRA_RUN_IN_SUB_THREAD)) {
+ // Create a new thread and run tests on it.
+ new Thread() {
+ @Override
+ public void run() {
+ runTests();
+ }
+ }.start();
+ } else {
+ // Post a task to run the tests. This allows us to not block
+ // onCreate and still run tests on the main thread.
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ runTests();
+ }
+ }, RUN_TESTS_DELAY_IN_MS);
+ }
+ }
+
+ private void runTests() {
+ // This directory is used by build/android/pylib/test_package_apk.py.
+ nativeRunTests(getFilesDir().getAbsolutePath(), getApplicationContext());
+ }
+
+ // Signal a failure of the native test loader to python scripts
+ // which run tests. For example, we look for
+ // RUNNER_FAILED build/android/test_package.py.
+ private void nativeTestFailed() {
+ Log.e(TAG, "[ RUNNER_FAILED ] could not load native library");
+ }
+
+ private void loadLibraries() {
+ for (String library : NativeLibraries.LIBRARIES) {
+ Log.i(TAG, "loading: " + library);
+ System.loadLibrary(library);
+ Log.i(TAG, "loaded: " + library);
+ }
+ }
+
+ private native void nativeRunTests(String filesDir, Context appContext);
+}
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/GtestComputer.java b/testing/android/junit/java/src/org/chromium/testing/local/GtestComputer.java
new file mode 100644
index 0000000..c6782d0
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/GtestComputer.java
@@ -0,0 +1,76 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.Computer;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * A Computer that logs the start and end of test cases googletest-style.
+ */
+public class GtestComputer extends Computer {
+
+ private final GtestLogger mLogger;
+
+ public GtestComputer(GtestLogger logger) {
+ mLogger = logger;
+ }
+
+ /**
+ * A wrapping Runner that logs the start and end of each test case.
+ */
+ private class GtestSuiteRunner extends Runner implements Filterable {
+ private final Runner mRunner;
+
+ public GtestSuiteRunner(Runner contained) {
+ mRunner = contained;
+ }
+
+ public Description getDescription() {
+ return mRunner.getDescription();
+ }
+
+ public void run(RunNotifier notifier) {
+ long startTimeMillis = System.currentTimeMillis();
+ mLogger.testCaseStarted(mRunner.getDescription(),
+ mRunner.getDescription().testCount());
+ mRunner.run(notifier);
+ mLogger.testCaseFinished(mRunner.getDescription(),
+ mRunner.getDescription().testCount(),
+ System.currentTimeMillis() - startTimeMillis);
+ }
+
+ public void filter(Filter filter) throws NoTestsRemainException {
+ if (mRunner instanceof Filterable) {
+ ((Filterable) mRunner).filter(filter);
+ }
+ }
+ }
+
+ /**
+ * Returns a suite of unit tests with each class runner wrapped by a
+ * GtestSuiteRunner.
+ */
+ @Override
+ public Runner getSuite(final RunnerBuilder builder, Class<?>[] classes)
+ throws InitializationError {
+ return super.getSuite(
+ new RunnerBuilder() {
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ return new GtestSuiteRunner(builder.runnerForClass(testClass));
+ }
+ }, classes);
+ }
+
+}
+
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/GtestFilter.java b/testing/android/junit/java/src/org/chromium/testing/local/GtestFilter.java
new file mode 100644
index 0000000..68dcbb8
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/GtestFilter.java
@@ -0,0 +1,95 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * Filters tests based on a googletest-style filter string.
+ */
+class GtestFilter extends Filter {
+
+ private final String mFilterString;
+
+ private final Set<Pattern> mPositiveRegexes;
+ private final Set<Pattern> mNegativeRegexes;
+
+ private static final Pattern ASTERISK = Pattern.compile("\\*");
+ private static final Pattern COLON = Pattern.compile(":");
+ private static final Pattern DASH = Pattern.compile("-");
+ private static final Pattern PERIOD = Pattern.compile("\\.");
+
+ /**
+ * Creates the filter and converts the provided googletest-style filter
+ * string into positive and negative regexes.
+ */
+ public GtestFilter(String filterString) {
+ mFilterString = filterString;
+ mPositiveRegexes = new HashSet<Pattern>();
+ mNegativeRegexes = new HashSet<Pattern>();
+
+ String[] filterStrings = COLON.split(filterString);
+ for (String f : filterStrings) {
+ if (f.isEmpty()) continue;
+
+ String sanitized = PERIOD.matcher(f).replaceAll("\\\\.");
+ sanitized = ASTERISK.matcher(sanitized).replaceAll(".*");
+ int negIndex = sanitized.indexOf('-');
+ if (negIndex == 0) {
+ mNegativeRegexes.add(Pattern.compile(sanitized.substring(1)));
+ } else if (negIndex != -1) {
+ String[] c = DASH.split(sanitized, 2);
+ mPositiveRegexes.add(Pattern.compile(c[0]));
+ mNegativeRegexes.add(Pattern.compile(c[1]));
+ } else {
+ mPositiveRegexes.add(Pattern.compile(sanitized));
+ }
+ }
+ }
+
+ /**
+ * Determines whether or not a test with the provided description should
+ * run based on the configured positive and negative regexes.
+ *
+ * A test should run if:
+ * - it's just a class, OR
+ * - it doesn't match any of the negative regexes, AND
+ * - either:
+ * - there are no configured positive regexes, OR
+ * - it matches at least one of the positive regexes.
+ */
+ @Override
+ public boolean shouldRun(Description description) {
+ if (description.getMethodName() == null) return true;
+
+ String gtestName = description.getClassName() + "." + description.getMethodName();
+ for (Pattern p : mNegativeRegexes) {
+ if (p.matcher(gtestName).matches()) return false;
+ }
+
+ if (mPositiveRegexes.isEmpty()) return true;
+
+ for (Pattern p : mPositiveRegexes) {
+ if (p.matcher(gtestName).matches()) return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a description of this filter.
+ */
+ @Override
+ public String describe() {
+ return "gtest-filter: " + mFilterString;
+ }
+
+}
+
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/GtestListener.java b/testing/android/junit/java/src/org/chromium/testing/local/GtestListener.java
new file mode 100644
index 0000000..122d135
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/GtestListener.java
@@ -0,0 +1,80 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/** A JUnit RunListener that emulates GTest output to the extent that it can.
+ */
+public class GtestListener extends RunListener {
+
+ private Set<Description> mFailedTests;
+ private final GtestLogger mLogger;
+ private long mRunStartTimeMillis;
+ private long mTestStartTimeMillis;
+ private int mTestsPassed;
+ private boolean mCurrentTestPassed;
+
+ public GtestListener(GtestLogger logger) {
+ mLogger = logger;
+ }
+
+ /** Called before any tests run.
+ */
+ @Override
+ public void testRunStarted(Description d) throws Exception {
+ mLogger.testRunStarted(d.testCount());
+ mRunStartTimeMillis = System.currentTimeMillis();
+ mTestsPassed = 0;
+ mFailedTests = new HashSet<Description>();
+ mCurrentTestPassed = true;
+ }
+
+ /** Called after all tests run.
+ */
+ @Override
+ public void testRunFinished(Result r) throws Exception {
+ long elapsedTimeMillis = System.currentTimeMillis() - mRunStartTimeMillis;
+ mLogger.testRunFinished(mTestsPassed, mFailedTests, elapsedTimeMillis);
+ }
+
+ /** Called when a test is about to start.
+ */
+ @Override
+ public void testStarted(Description d) throws Exception {
+ mCurrentTestPassed = true;
+ mLogger.testStarted(d);
+ mTestStartTimeMillis = System.currentTimeMillis();
+ }
+
+ /** Called when a test has just finished.
+ */
+ @Override
+ public void testFinished(Description d) throws Exception {
+ long testElapsedTimeMillis = System.currentTimeMillis() - mTestStartTimeMillis;
+ mLogger.testFinished(d, mCurrentTestPassed, testElapsedTimeMillis);
+ if (mCurrentTestPassed) {
+ ++mTestsPassed;
+ } else {
+ mFailedTests.add(d);
+ }
+ }
+
+ /** Called when a test fails.
+ */
+ @Override
+ public void testFailure(Failure f) throws Exception {
+ mCurrentTestPassed = false;
+ mLogger.testFailed(f);
+ }
+
+}
+
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/GtestLogger.java b/testing/android/junit/java/src/org/chromium/testing/local/GtestLogger.java
new file mode 100644
index 0000000..0972374
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/GtestLogger.java
@@ -0,0 +1,109 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+
+import java.io.PrintStream;
+import java.util.Set;
+
+/**
+ * Formats and logs test status information in googletest-style.
+ */
+public class GtestLogger {
+
+ private final PrintStream mOutputStream;
+
+ public GtestLogger(PrintStream outputStream) {
+ mOutputStream = outputStream;
+ }
+
+ /**
+ * Logs the start of an individual test.
+ */
+ public void testStarted(Description test) {
+ mOutputStream.format("[ RUN ] %s.%s", test.getClassName(), test.getMethodName());
+ mOutputStream.println();
+ }
+
+ /**
+ * Logs a test failure.
+ */
+ public void testFailed(Failure f) {
+ if (f.getException() != null) {
+ f.getException().printStackTrace(mOutputStream);
+ }
+ }
+
+ /**
+ * Logs the end of an individual test.
+ */
+ public void testFinished(Description test, boolean passed, long elapsedTimeMillis) {
+ if (passed) {
+ mOutputStream.format("[ OK ] %s.%s (%d ms)",
+ test.getClassName(), test.getMethodName(), elapsedTimeMillis);
+ } else {
+ mOutputStream.format("[ FAILED ] %s.%s (%d ms)",
+ test.getClassName(), test.getMethodName(), elapsedTimeMillis);
+ }
+ mOutputStream.println();
+ }
+
+ /**
+ * Logs the start of a test case.
+ */
+ public void testCaseStarted(Description test, int testCount) {
+ mOutputStream.format("[----------] Run %d test cases from %s", testCount,
+ test.getClassName());
+ mOutputStream.println();
+ }
+
+ /**
+ * Logs the end of a test case.
+ */
+ public void testCaseFinished(Description test, int testCount,
+ long elapsedTimeMillis) {
+ mOutputStream.format("[----------] Run %d test cases from %s (%d ms)",
+ testCount, test.getClassName(), elapsedTimeMillis);
+ mOutputStream.println();
+ mOutputStream.println();
+ }
+
+ /**
+ * Logs the start of a test run.
+ */
+ public void testRunStarted(int testCount) {
+ mOutputStream.format("[==========] Running %d tests.", testCount);
+ mOutputStream.println();
+ mOutputStream.println("[----------] Global test environment set-up.");
+ mOutputStream.println();
+ }
+
+ /**
+ * Logs the end of a test run.
+ */
+ public void testRunFinished(int passedTestCount, Set<Description> failedTests,
+ long elapsedTimeMillis) {
+ int totalTestCount = passedTestCount + failedTests.size();
+ mOutputStream.println("[----------] Global test environment tear-down.");
+ mOutputStream.format("[==========] %d tests ran. (%d ms total)",
+ totalTestCount, elapsedTimeMillis);
+ mOutputStream.println();
+ mOutputStream.format("[ PASSED ] %d tests.", passedTestCount);
+ mOutputStream.println();
+ if (!failedTests.isEmpty()) {
+ mOutputStream.format("[ FAILED ] %d tests.", failedTests.size());
+ mOutputStream.println();
+ for (Description d : failedTests) {
+ mOutputStream.format("[ FAILED ] %s.%s", d.getClassName(), d.getMethodName());
+ mOutputStream.println();
+ }
+ mOutputStream.println();
+ }
+ }
+
+}
+
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/JunitTestArgParser.java b/testing/android/junit/java/src/org/chromium/testing/local/JunitTestArgParser.java
new file mode 100644
index 0000000..9de7874
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/JunitTestArgParser.java
@@ -0,0 +1,90 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Parses command line arguments for JunitTestMain.
+ */
+public class JunitTestArgParser {
+
+ private final Set<String> mPackageFilters;
+ private final Set<Class<?>> mRunnerFilters;
+ private final Set<String> mGtestFilters;
+
+ public static JunitTestArgParser parse(String[] args) {
+
+ JunitTestArgParser parsed = new JunitTestArgParser();
+
+ for (int i = 0; i < args.length; ++i) {
+ if (args[i].startsWith("-")) {
+ String argName;
+ if (args[i].startsWith("-", 1)) {
+ argName = args[i].substring(2, args[i].length());
+ } else {
+ argName = args[i].substring(1, args[i].length());
+ }
+ try {
+ if ("package-filter".equals(argName)) {
+ // Read the command line argument after the flag.
+ parsed.addPackageFilter(args[++i]);
+ } else if ("runner-filter".equals(argName)) {
+ // Read the command line argument after the flag.
+ parsed.addRunnerFilter(Class.forName(args[++i]));
+ } else if ("gtest-filter".equals(argName)) {
+ // Read the command line argument after the flag.
+ parsed.addGtestFilter(args[++i]);
+ } else {
+ System.out.println("Ignoring flag: \"" + argName + "\"");
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ System.err.println("No value specified for argument \"" + argName + "\"");
+ System.exit(1);
+ } catch (ClassNotFoundException e) {
+ System.err.println("Class not found. (" + e.toString() + ")");
+ System.exit(1);
+ }
+ } else {
+ System.out.println("Ignoring argument: \"" + args[i] + "\"");
+ }
+ }
+
+ return parsed;
+ }
+
+ private JunitTestArgParser() {
+ mPackageFilters = new HashSet<String>();
+ mRunnerFilters = new HashSet<Class<?>>();
+ mGtestFilters = new HashSet<String>();
+ }
+
+ public Set<String> getPackageFilters() {
+ return mPackageFilters;
+ }
+
+ public Set<Class<?>> getRunnerFilters() {
+ return mRunnerFilters;
+ }
+
+ public Set<String> getGtestFilters() {
+ return mGtestFilters;
+ }
+
+ private void addPackageFilter(String packageFilter) {
+ mPackageFilters.add(packageFilter);
+ }
+
+ private void addRunnerFilter(Class<?> runnerFilter) {
+ mRunnerFilters.add(runnerFilter);
+ }
+
+ private void addGtestFilter(String gtestFilter) {
+ mGtestFilters.add(gtestFilter);
+ }
+
+}
+
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/JunitTestMain.java b/testing/android/junit/java/src/org/chromium/testing/local/JunitTestMain.java
new file mode 100644
index 0000000..d9c468d
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/JunitTestMain.java
@@ -0,0 +1,96 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Pattern;
+
+/**
+ * Runs tests based on JUnit from the classpath on the host JVM based on the
+ * provided filter configurations.
+ */
+public final class JunitTestMain {
+
+ private static final String CLASS_FILE_EXT = ".class";
+
+ private static final Pattern COLON = Pattern.compile(":");
+ private static final Pattern FORWARD_SLASH = Pattern.compile("/");
+
+ private JunitTestMain() {
+ }
+
+ /**
+ * Finds all classes on the class path annotated with RunWith.
+ */
+ public static Class[] findClassesFromClasspath() {
+ String[] jarPaths = COLON.split(System.getProperty("java.class.path"));
+ LinkedList<Class> classes = new LinkedList<Class>();
+ for (String jp : jarPaths) {
+ try {
+ JarFile jf = new JarFile(jp);
+ for (Enumeration<JarEntry> eje = jf.entries(); eje.hasMoreElements();) {
+ JarEntry je = eje.nextElement();
+ String cn = je.getName();
+ if (!cn.endsWith(CLASS_FILE_EXT) || cn.indexOf('$') != -1) {
+ continue;
+ }
+ cn = cn.substring(0, cn.length() - CLASS_FILE_EXT.length());
+ cn = FORWARD_SLASH.matcher(cn).replaceAll(".");
+ Class<?> c = classOrNull(cn);
+ if (c != null && c.isAnnotationPresent(RunWith.class)) {
+ classes.push(c);
+ }
+ }
+ jf.close();
+ } catch (IOException e) {
+ System.err.println("Error while reading classes from " + jp);
+ }
+ }
+ return classes.toArray(new Class[classes.size()]);
+ }
+
+ private static Class<?> classOrNull(String className) {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ System.err.println("Class not found: " + className);
+ } catch (NoClassDefFoundError e) {
+ System.err.println("Class definition not found: " + className);
+ } catch (Exception e) {
+ System.err.println("Other exception while reading class: " + className);
+ }
+ return null;
+ }
+
+ public static void main(String[] args) {
+ JunitTestArgParser parser = JunitTestArgParser.parse(args);
+
+ JUnitCore core = new JUnitCore();
+ GtestLogger logger = new GtestLogger(System.out);
+ core.addListener(new GtestListener(logger));
+ Class[] classes = findClassesFromClasspath();
+ Request testRequest = Request.classes(new GtestComputer(logger), classes);
+ for (String packageFilter : parser.getPackageFilters()) {
+ testRequest = testRequest.filterWith(new PackageFilter(packageFilter));
+ }
+ for (Class<?> runnerFilter : parser.getRunnerFilters()) {
+ testRequest = testRequest.filterWith(new RunnerFilter(runnerFilter));
+ }
+ for (String gtestFilter : parser.getGtestFilters()) {
+ testRequest = testRequest.filterWith(new GtestFilter(gtestFilter));
+ }
+ System.exit(core.run(testRequest).wasSuccessful() ? 0 : 1);
+ }
+
+}
+
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/PackageFilter.java b/testing/android/junit/java/src/org/chromium/testing/local/PackageFilter.java
new file mode 100644
index 0000000..4d6a580
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/PackageFilter.java
@@ -0,0 +1,41 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Filters tests based on the package.
+ */
+class PackageFilter extends Filter {
+
+ private final String mFilterString;
+
+ /**
+ * Creates the filter.
+ */
+ public PackageFilter(String filterString) {
+ mFilterString = filterString;
+ }
+
+ /**
+ * Determines whether or not a test with the provided description should
+ * run based on its package.
+ */
+ @Override
+ public boolean shouldRun(Description description) {
+ return description.getTestClass().getPackage().getName().equals(mFilterString);
+ }
+
+ /**
+ * Returns a description of this filter.
+ */
+ @Override
+ public String describe() {
+ return "package-filter: " + mFilterString;
+ }
+
+}
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/RunnerFilter.java b/testing/android/junit/java/src/org/chromium/testing/local/RunnerFilter.java
new file mode 100644
index 0000000..e32753e
--- /dev/null
+++ b/testing/android/junit/java/src/org/chromium/testing/local/RunnerFilter.java
@@ -0,0 +1,45 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Filters tests based on the Runner class annotating the test class.
+ */
+class RunnerFilter extends Filter {
+
+ private final Class<?> mRunnerClass;
+
+ /**
+ * Creates the filter.
+ */
+ public RunnerFilter(Class<?> runnerClass) {
+ mRunnerClass = runnerClass;
+ }
+
+ /**
+ * Determines whether or not a test with the provided description should
+ * run based on the Runner class annotating the test class.
+ */
+ @Override
+ public boolean shouldRun(Description description) {
+ Class<?> c = description.getTestClass();
+ return c != null && c.isAnnotationPresent(RunWith.class)
+ && c.getAnnotation(RunWith.class).value() == mRunnerClass;
+ }
+
+ /**
+ * Returns a description of this filter.
+ */
+ @Override
+ public String describe() {
+ return "runner-filter: " + mRunnerClass.getName();
+ }
+
+}
+
diff --git a/testing/android/junit/javatests/src/org/chromium/testing/local/GtestFilterTest.java b/testing/android/junit/javatests/src/org/chromium/testing/local/GtestFilterTest.java
new file mode 100644
index 0000000..7b0e0f5
--- /dev/null
+++ b/testing/android/junit/javatests/src/org/chromium/testing/local/GtestFilterTest.java
@@ -0,0 +1,118 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * Unit tests for GtestFilter.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class GtestFilterTest {
+
+ @Test
+ public void testDescription() {
+ Filter filterUnderTest = new GtestFilter("TestClass.*");
+ Assert.assertEquals("gtest-filter: TestClass.*", filterUnderTest.describe());
+ }
+
+ @Test
+ public void testNoFilter() {
+ Filter filterUnderTest = new GtestFilter("");
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+ @Test
+ public void testPositiveFilterExplicit() {
+ Filter filterUnderTest = new GtestFilter("TestClass.testMethod");
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+ @Test
+ public void testPositiveFilterClassRegex() {
+ Filter filterUnderTest = new GtestFilter("TestClass.*");
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+ @Test
+ public void testNegativeFilterExplicit() {
+ Filter filterUnderTest = new GtestFilter("-TestClass.testMethod");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+ @Test
+ public void testNegativeFilterClassRegex() {
+ Filter filterUnderTest = new GtestFilter("-TestClass.*");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+ @Test
+ public void testPositiveAndNegativeFilter() {
+ Filter filterUnderTest = new GtestFilter("TestClass.*-TestClass.testMethod");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+ @Test
+ public void testMultiplePositiveFilters() {
+ Filter filterUnderTest = new GtestFilter(
+ "TestClass.otherTestMethod:OtherTestClass.otherTestMethod");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "otherTestMethod")));
+ }
+
+ @Test
+ public void testMultipleFiltersPositiveAndNegative() {
+ Filter filterUnderTest = new GtestFilter("TestClass.*:-TestClass.testMethod");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "testMethod")));
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription("TestClass", "otherTestMethod")));
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("OtherTestClass", "testMethod")));
+ }
+
+}
+
diff --git a/testing/android/junit/javatests/src/org/chromium/testing/local/GtestLoggerTest.java b/testing/android/junit/javatests/src/org/chromium/testing/local/GtestLoggerTest.java
new file mode 100644
index 0000000..2a442fc
--- /dev/null
+++ b/testing/android/junit/javatests/src/org/chromium/testing/local/GtestLoggerTest.java
@@ -0,0 +1,144 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Unit tests for GtestLogger.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class GtestLoggerTest {
+
+ @Test
+ public void testTestStarted() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testStarted(
+ Description.createTestDescription(GtestLoggerTest.class, "testTestStarted"));
+ Assert.assertEquals(
+ "[ RUN ] org.chromium.testing.local.GtestLoggerTest.testTestStarted\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestFinishedPassed() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testFinished(
+ Description.createTestDescription(GtestLoggerTest.class, "testTestFinishedPassed"),
+ true, 123);
+ Assert.assertEquals(
+ "[ OK ] org.chromium.testing.local.GtestLoggerTest.testTestFinishedPassed" +
+ " (123 ms)\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestFinishedFailed() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testFinished(
+ Description.createTestDescription(GtestLoggerTest.class, "testTestFinishedPassed"),
+ false, 123);
+ Assert.assertEquals(
+ "[ FAILED ] org.chromium.testing.local.GtestLoggerTest.testTestFinishedPassed" +
+ " (123 ms)\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestCaseStarted() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testCaseStarted(
+ Description.createSuiteDescription(GtestLoggerTest.class), 456);
+ Assert.assertEquals(
+ "[----------] Run 456 test cases from org.chromium.testing.local.GtestLoggerTest\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestCaseFinished() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testCaseFinished(
+ Description.createSuiteDescription(GtestLoggerTest.class), 456, 123);
+ Assert.assertEquals(
+ "[----------] Run 456 test cases from org.chromium.testing.local.GtestLoggerTest" +
+ " (123 ms)\n\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestRunStarted() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testRunStarted(1234);
+ Assert.assertEquals(
+ "[==========] Running 1234 tests.\n" +
+ "[----------] Global test environment set-up.\n\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestRunFinishedNoFailures() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+ loggerUnderTest.testRunFinished(1234, new HashSet<Description>(), 4321);
+ Assert.assertEquals(
+ "[----------] Global test environment tear-down.\n" +
+ "[==========] 1234 tests ran. (4321 ms total)\n" +
+ "[ PASSED ] 1234 tests.\n",
+ actual.toString());
+ }
+
+ @Test
+ public void testTestRunFinishedWithFailures() {
+ ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ GtestLogger loggerUnderTest = new GtestLogger(new PrintStream(actual));
+
+ Set<Description> failures = new TreeSet<Description>(new DescriptionComparator());
+ failures.add(Description.createTestDescription(
+ "GtestLoggerTest", "testTestRunFinishedNoFailures"));
+ failures.add(Description.createTestDescription(
+ "GtestLoggerTest", "testTestRunFinishedWithFailures"));
+
+ loggerUnderTest.testRunFinished(1232, failures, 4312);
+ Assert.assertEquals(
+ "[----------] Global test environment tear-down.\n" +
+ "[==========] 1234 tests ran. (4312 ms total)\n" +
+ "[ PASSED ] 1232 tests.\n" +
+ "[ FAILED ] 2 tests.\n" +
+ "[ FAILED ] GtestLoggerTest.testTestRunFinishedNoFailures\n" +
+ "[ FAILED ] GtestLoggerTest.testTestRunFinishedWithFailures\n" +
+ "\n",
+ actual.toString());
+ }
+
+ private static class DescriptionComparator implements Comparator<Description>, Serializable {
+ @Override
+ public int compare(Description o1, Description o2) {
+ return toGtestStyleString(o1).compareTo(toGtestStyleString(o2));
+ }
+
+ private static String toGtestStyleString(Description d) {
+ return d.getClassName() + "." + d.getMethodName();
+ }
+ }
+}
+
diff --git a/testing/android/junit/javatests/src/org/chromium/testing/local/PackageFilterTest.java b/testing/android/junit/javatests/src/org/chromium/testing/local/PackageFilterTest.java
new file mode 100644
index 0000000..4427676
--- /dev/null
+++ b/testing/android/junit/javatests/src/org/chromium/testing/local/PackageFilterTest.java
@@ -0,0 +1,47 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * Unit tests for PackageFilter.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class PackageFilterTest {
+
+ @Test
+ public void testDescription() {
+ Filter filterUnderTest = new PackageFilter("test.package");
+ Assert.assertEquals("package-filter: test.package", filterUnderTest.describe());
+ }
+
+ @Test
+ public void testNoFilter() {
+ Filter filterUnderTest = new PackageFilter("");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription(PackageFilterTest.class, "testNoFilter")));
+ }
+
+ @Test
+ public void testFilterHit() {
+ Filter filterUnderTest = new PackageFilter("org.chromium.testing.local");
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription(PackageFilterTest.class, "testWithFilter")));
+ }
+
+ @Test
+ public void testFilterMiss() {
+ Filter filterUnderTest = new PackageFilter("org.chromium.native_test");
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription(PackageFilterTest.class, "testWithFilter")));
+ }
+
+}
diff --git a/testing/android/junit/javatests/src/org/chromium/testing/local/RunnerFilterTest.java b/testing/android/junit/javatests/src/org/chromium/testing/local/RunnerFilterTest.java
new file mode 100644
index 0000000..9a73be7
--- /dev/null
+++ b/testing/android/junit/javatests/src/org/chromium/testing/local/RunnerFilterTest.java
@@ -0,0 +1,56 @@
+// Copyright 2014 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.
+
+package org.chromium.testing.local;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Suite;
+
+/**
+ * Unit tests for RunnerFilter.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class RunnerFilterTest {
+
+ @Test
+ public void testDescription() {
+ Filter filterUnderTest = new RunnerFilter(BlockJUnit4ClassRunner.class);
+ Assert.assertEquals("runner-filter: org.junit.runners.BlockJUnit4ClassRunner",
+ filterUnderTest.describe());
+ }
+
+ @Test
+ public void testNoFilter() {
+ Filter filterUnderTest = new RunnerFilter(null);
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription(RunnerFilterTest.class, "testNoFilter")));
+ }
+
+ @Test
+ public void testFilterHit() {
+ Filter filterUnderTest = new RunnerFilter(BlockJUnit4ClassRunner.class);
+ Assert.assertTrue(filterUnderTest.shouldRun(
+ Description.createTestDescription(RunnerFilterTest.class, "testFilterHit")));
+ }
+
+ @Test
+ public void testFilterMiss() {
+ Filter filterUnderTest = new RunnerFilter(Suite.class);
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription(RunnerFilterTest.class, "testFilterMiss")));
+ }
+
+ @Test
+ public void testClassNotFound() {
+ Filter filterUnderTest = new RunnerFilter(BlockJUnit4ClassRunner.class);
+ Assert.assertFalse(filterUnderTest.shouldRun(
+ Description.createTestDescription("FakeTestClass", "fakeTestMethod")));
+ }
+}
+
diff --git a/testing/android/junit/junit_test.gyp b/testing/android/junit/junit_test.gyp
new file mode 100644
index 0000000..35b3be4
--- /dev/null
+++ b/testing/android/junit/junit_test.gyp
@@ -0,0 +1,39 @@
+# Copyright 2014 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.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'junit_test_support',
+ 'type': 'none',
+ 'dependencies': [
+ '../../../third_party/junit/junit.gyp:junit_jar',
+ ],
+ 'variables': {
+ 'src_paths': [
+ 'java/src',
+ ],
+ },
+ 'includes': [
+ '../../../build/host_jar.gypi',
+ ],
+ },
+ {
+ 'target_name': 'junit_unit_tests',
+ 'type': 'none',
+ 'dependencies': [
+ 'junit_test_support',
+ ],
+ 'variables': {
+ 'main_class': 'org.chromium.testing.local.JunitTestMain',
+ 'src_paths': [
+ 'javatests/src',
+ ],
+ },
+ 'includes': [
+ '../../../build/host_jar.gypi',
+ ],
+ },
+ ],
+}
diff --git a/testing/android/native_test.gyp b/testing/android/native_test.gyp
new file mode 100644
index 0000000..14f3229
--- /dev/null
+++ b/testing/android/native_test.gyp
@@ -0,0 +1,60 @@
+# Copyright (c) 2012 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.
+
+{
+ 'conditions': [
+ ['OS=="android"', {
+ 'targets': [
+ {
+ # GN: //testing/android:native_test_native_code
+ 'target_name': 'native_test_native_code',
+ 'message': 'building native pieces of native test package',
+ 'type': 'static_library',
+ 'sources': [
+ 'native_test_launcher.cc',
+ ],
+ 'direct_dependent_settings': {
+ 'ldflags!': [
+ # JNI_OnLoad is implemented in a .a and we need to
+ # re-export in the .so.
+ '-Wl,--exclude-libs=ALL',
+ ],
+ },
+ 'dependencies': [
+ '../../base/base.gyp:base',
+ '../../base/base.gyp:test_support_base',
+ '../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ '../gtest.gyp:gtest',
+ 'native_test_jni_headers',
+ 'native_test_util',
+ ],
+ },
+ {
+ # GN: //testing/android:native_test_jni_headers
+ 'target_name': 'native_test_jni_headers',
+ 'type': 'none',
+ 'sources': [
+ 'java/src/org/chromium/native_test/ChromeNativeTestActivity.java'
+ ],
+ 'variables': {
+ 'jni_gen_package': 'testing',
+ },
+ 'includes': [ '../../build/jni_generator.gypi' ],
+ },
+ {
+ # GN: //testing/android:native_test_util
+ 'target_name': 'native_test_util',
+ 'type': 'static_library',
+ 'sources': [
+ 'native_test_util.cc',
+ 'native_test_util.h',
+ ],
+ 'dependencies': [
+ '../../base/base.gyp:base',
+ ],
+ },
+ ],
+ }]
+ ],
+}
diff --git a/testing/android/native_test_launcher.cc b/testing/android/native_test_launcher.cc
new file mode 100644
index 0000000..63e389a
--- /dev/null
+++ b/testing/android/native_test_launcher.cc
@@ -0,0 +1,200 @@
+// Copyright (c) 2012 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.
+
+// This class sets up the environment for running the native tests inside an
+// android application. It outputs (to a fifo) markers identifying the
+// START/PASSED/CRASH of the test suite, FAILURE/SUCCESS of individual tests,
+// etc.
+// These markers are read by the test runner script to generate test results.
+// It installs signal handlers to detect crashes.
+
+#include <android/log.h>
+#include <signal.h>
+
+#include "base/android/base_jni_registrar.h"
+#include "base/android/fifo_utils.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/at_exit.h"
+#include "base/base_switches.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "gtest/gtest.h"
+#include "jni/ChromeNativeTestActivity_jni.h"
+#include "testing/android/native_test_util.h"
+
+using testing::native_test_util::ArgsToArgv;
+using testing::native_test_util::ParseArgsFromCommandLineFile;
+using testing::native_test_util::ScopedMainEntryLogger;
+
+// The main function of the program to be wrapped as a test apk.
+extern int main(int argc, char** argv);
+
+namespace {
+
+// These two command line flags are supported for DumpRenderTree, which needs
+// three fifos rather than a combined one: one for stderr, stdin and stdout.
+const char kSeparateStderrFifo[] = "separate-stderr-fifo";
+const char kCreateStdinFifo[] = "create-stdin-fifo";
+
+// The test runner script writes the command line file in
+// "/data/local/tmp".
+static const char kCommandLineFilePath[] =
+ "/data/local/tmp/chrome-native-tests-command-line";
+
+const char kLogTag[] = "chromium";
+const char kCrashedMarker[] = "[ CRASHED ]\n";
+
+// The list of signals which are considered to be crashes.
+const int kExceptionSignals[] = {
+ SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, -1
+};
+
+struct sigaction g_old_sa[NSIG];
+
+// This function runs in a compromised context. It should not allocate memory.
+void SignalHandler(int sig, siginfo_t* info, void* reserved) {
+ // Output the crash marker.
+ write(STDOUT_FILENO, kCrashedMarker, sizeof(kCrashedMarker));
+ g_old_sa[sig].sa_sigaction(sig, info, reserved);
+}
+
+// TODO(nileshagrawal): now that we're using FIFO, test scripts can detect EOF.
+// Remove the signal handlers.
+void InstallHandlers() {
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_SIGINFO;
+
+ for (unsigned int i = 0; kExceptionSignals[i] != -1; ++i) {
+ sigaction(kExceptionSignals[i], &sa, &g_old_sa[kExceptionSignals[i]]);
+ }
+}
+
+// Writes printf() style string to Android's logger where |priority| is one of
+// the levels defined in <android/log.h>.
+void AndroidLog(int priority, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ __android_log_vprint(priority, kLogTag, format, args);
+ va_end(args);
+}
+
+// Ensures that the fifo at |path| is created by deleting whatever is at |path|
+// prior to (re)creating the fifo, otherwise logs the error and terminates the
+// program.
+void EnsureCreateFIFO(const base::FilePath& path) {
+ unlink(path.value().c_str());
+ if (base::android::CreateFIFO(path, 0666))
+ return;
+
+ AndroidLog(ANDROID_LOG_ERROR, "Failed to create fifo %s: %s\n",
+ path.value().c_str(), strerror(errno));
+ exit(EXIT_FAILURE);
+}
+
+// Ensures that |stream| is redirected to |path|, otherwise logs the error and
+// terminates the program.
+void EnsureRedirectStream(FILE* stream,
+ const base::FilePath& path,
+ const char* mode) {
+ if (base::android::RedirectStream(stream, path, mode))
+ return;
+
+ AndroidLog(ANDROID_LOG_ERROR, "Failed to redirect stream to file: %s: %s\n",
+ path.value().c_str(), strerror(errno));
+ exit(EXIT_FAILURE);
+}
+
+} // namespace
+
+static void RunTests(JNIEnv* env,
+ jobject obj,
+ jstring jfiles_dir,
+ jobject app_context) {
+ base::AtExitManager exit_manager;
+
+ // Command line initialized basically, will be fully initialized later.
+ static const char* const kInitialArgv[] = { "ChromeTestActivity" };
+ CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
+
+ // Set the application context in base.
+ base::android::ScopedJavaLocalRef<jobject> scoped_context(
+ env, env->NewLocalRef(app_context));
+ base::android::InitApplicationContext(env, scoped_context);
+ base::android::RegisterJni(env);
+
+ std::vector<std::string> args;
+ ParseArgsFromCommandLineFile(kCommandLineFilePath, &args);
+
+ std::vector<char*> argv;
+ int argc = ArgsToArgv(args, &argv);
+
+ // Fully initialize command line with arguments.
+ CommandLine::ForCurrentProcess()->AppendArguments(
+ CommandLine(argc, &argv[0]), false);
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+
+ base::FilePath files_dir(
+ base::android::ConvertJavaStringToUTF8(env, jfiles_dir));
+
+ // A few options, such "--gtest_list_tests", will just use printf directly
+ // Always redirect stdout to a known file.
+ base::FilePath fifo_path(files_dir.Append(base::FilePath("test.fifo")));
+ EnsureCreateFIFO(fifo_path);
+
+ base::FilePath stderr_fifo_path, stdin_fifo_path;
+
+ // DumpRenderTree needs a separate fifo for the stderr output. For all
+ // other tests, insert stderr content to the same fifo we use for stdout.
+ if (command_line.HasSwitch(kSeparateStderrFifo)) {
+ stderr_fifo_path = files_dir.Append(base::FilePath("stderr.fifo"));
+ EnsureCreateFIFO(stderr_fifo_path);
+ }
+
+ // DumpRenderTree uses stdin to receive input about which test to run.
+ if (command_line.HasSwitch(kCreateStdinFifo)) {
+ stdin_fifo_path = files_dir.Append(base::FilePath("stdin.fifo"));
+ EnsureCreateFIFO(stdin_fifo_path);
+ }
+
+ // Only redirect the streams after all fifos have been created.
+ EnsureRedirectStream(stdout, fifo_path, "w");
+ if (!stdin_fifo_path.empty())
+ EnsureRedirectStream(stdin, stdin_fifo_path, "r");
+ if (!stderr_fifo_path.empty())
+ EnsureRedirectStream(stderr, stderr_fifo_path, "w");
+ else
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+
+ if (command_line.HasSwitch(switches::kWaitForDebugger)) {
+ AndroidLog(ANDROID_LOG_VERBOSE,
+ "Native test waiting for GDB because flag %s was supplied",
+ switches::kWaitForDebugger);
+ base::debug::WaitForDebugger(24 * 60 * 60, false);
+ }
+
+ ScopedMainEntryLogger scoped_main_entry_logger;
+ main(argc, &argv[0]);
+}
+
+// This is called by the VM when the shared library is first loaded.
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ // Install signal handlers to detect crashes.
+ InstallHandlers();
+
+ base::android::InitVM(vm);
+ JNIEnv* env = base::android::AttachCurrentThread();
+ if (!RegisterNativesImpl(env)) {
+ return -1;
+ }
+
+ return JNI_VERSION_1_4;
+}
diff --git a/testing/android/native_test_util.cc b/testing/android/native_test_util.cc
new file mode 100644
index 0000000..98f32c7
--- /dev/null
+++ b/testing/android/native_test_util.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2013 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.
+
+#include "testing/android/native_test_util.h"
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+
+namespace {
+
+void ParseArgsFromString(const std::string& command_line,
+ std::vector<std::string>* args) {
+ base::StringTokenizer tokenizer(command_line, base::kWhitespaceASCII);
+ tokenizer.set_quote_chars("\"");
+ while (tokenizer.GetNext()) {
+ std::string token;
+ base::RemoveChars(tokenizer.token(), "\"", &token);
+ args->push_back(token);
+ }
+}
+
+} // namespace
+
+namespace testing {
+namespace native_test_util {
+
+void ParseArgsFromCommandLineFile(
+ const char* path, std::vector<std::string>* args) {
+ base::FilePath command_line(path);
+ std::string command_line_string;
+ if (base::ReadFileToString(command_line, &command_line_string)) {
+ ParseArgsFromString(command_line_string, args);
+ }
+}
+
+int ArgsToArgv(const std::vector<std::string>& args,
+ std::vector<char*>* argv) {
+ // We need to pass in a non-const char**.
+ int argc = args.size();
+
+ argv->resize(argc + 1);
+ for (int i = 0; i < argc; ++i) {
+ (*argv)[i] = const_cast<char*>(args[i].c_str());
+ }
+ (*argv)[argc] = NULL; // argv must be NULL terminated.
+
+ return argc;
+}
+
+} // namespace native_test_util
+} // namespace testing
diff --git a/testing/android/native_test_util.h b/testing/android/native_test_util.h
new file mode 100644
index 0000000..a756739
--- /dev/null
+++ b/testing/android/native_test_util.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2013 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.
+
+#ifndef TESTING_ANDROID_NATIVE_TEST_UTIL_
+#define TESTING_ANDROID_NATIVE_TEST_UTIL_
+
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+// Helper methods for setting up environment for running gtest tests
+// inside an APK.
+namespace testing {
+namespace native_test_util {
+
+class ScopedMainEntryLogger {
+ public:
+ ScopedMainEntryLogger() {
+ printf(">>ScopedMainEntryLogger\n");
+ }
+
+ ~ScopedMainEntryLogger() {
+ printf("<<ScopedMainEntryLogger\n");
+ fflush(stdout);
+ fflush(stderr);
+ }
+};
+
+void ParseArgsFromCommandLineFile(
+ const char* path, std::vector<std::string>* args);
+int ArgsToArgv(const std::vector<std::string>& args, std::vector<char*>* argv);
+
+} // namespace native_test_util
+} // namespace testing
+
+#endif // TESTING_ANDROID_NATIVE_TEST_UTIL_
diff --git a/testing/buildbot/OWNERS b/testing/buildbot/OWNERS
new file mode 100644
index 0000000..c70be62
--- /dev/null
+++ b/testing/buildbot/OWNERS
@@ -0,0 +1,13 @@
+# This is needed because of * in testing/OWNERS .
+# This is reserved for people that are comfortably with buildbot recipes
+# and understand the implications of changing these files.
+set noparent
+
+cmp@chromium.org
+darin@chromium.org
+dpranke@chromium.org
+jam@chromium.org
+jochen@chromium.org
+machenbach@chromium.org
+phajdan.jr@chromium.org
+sky@chromium.org
diff --git a/testing/buildbot/chromium.chrome.json b/testing/buildbot/chromium.chrome.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/testing/buildbot/chromium.chrome.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
new file mode 100644
index 0000000..e6bfa04
--- /dev/null
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -0,0 +1,244 @@
+{
+ "Linux ChromiumOS Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 5
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chromeos_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ {
+ "test": "ash_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "app_list_unittests",
+ "message_center_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sql_unittests",
+ "nacl_loader_unittests",
+ "athena_unittests",
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ "chromevox_tests"
+ ]
+ },
+ "Linux ChromiumOS Tests (2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux ChromiumOS Ozone Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_shell_unittests",
+ "ash_unittests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "chromeos_unittests",
+ "components_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ozone_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ "app_list_unittests",
+ "message_center_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "nacl_loader_unittests",
+ "athena_unittests"
+ ]
+ },
+ "Linux ChromiumOS Ozone Tests (2)": {
+ "gtest_tests": [
+ "interactive_ui_tests",
+ "browser_tests",
+ "content_browsertests",
+ "app_shell_browsertests",
+ "chromevox_tests"
+ ]
+ },
+ "Linux ChromiumOS Tests (dbg)(1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chromeos_unittests",
+ "components_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "extensions_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "device_unittests",
+ "display_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ {
+ "test": "ash_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "app_list_unittests",
+ "message_center_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sql_unittests",
+ "nacl_loader_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 20
+ }
+ },
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "athena_unittests",
+ "gcm_unit_tests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 3
+ }
+ }
+ ]
+ },
+ "Linux ChromiumOS Tests (dbg)(2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux ChromiumOS Tests (dbg)(3)": {
+ "gtest_tests": [
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
new file mode 100644
index 0000000..b8cdd2f
--- /dev/null
+++ b/testing/buildbot/chromium.fyi.json
@@ -0,0 +1,298 @@
+{
+ "Linux Trusty": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_unittests",
+ "aura_unittests",
+ "interactive_ui_tests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "events_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "unit_tests",
+ "views_unittests",
+ "wm_unittests",
+ "sql_unittests",
+ "browser_tests",
+ "content_browsertests",
+ "mojo_apps_js_unittests",
+ "mojo_clipboard_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_surfaces_lib_unittests",
+ "mojo_system_unittests",
+ "nacl_loader_unittests"
+ ]
+ },
+ "Linux Trusty (dbg)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_unittests",
+ "aura_unittests",
+ "interactive_ui_tests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "events_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "unit_tests",
+ "views_unittests",
+ "wm_unittests",
+ "sql_unittests",
+ "browser_tests",
+ "content_browsertests",
+ "mojo_apps_js_unittests",
+ "mojo_clipboard_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_surfaces_lib_unittests",
+ "mojo_system_unittests",
+ "nacl_loader_unittests"
+ ]
+ },
+ "Linux Trusty (32)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_unittests",
+ "aura_unittests",
+ "interactive_ui_tests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "events_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "unit_tests",
+ "views_unittests",
+ "wm_unittests",
+ "sql_unittests",
+ "browser_tests",
+ "content_browsertests",
+ "mojo_apps_js_unittests",
+ "mojo_clipboard_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_surfaces_lib_unittests",
+ "mojo_system_unittests",
+ "nacl_loader_unittests"
+ ]
+ },
+ "Linux Trusty (dbg)(32)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_unittests",
+ "aura_unittests",
+ "interactive_ui_tests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "events_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "unit_tests",
+ "views_unittests",
+ "wm_unittests",
+ "sql_unittests",
+ "browser_tests",
+ "content_browsertests",
+ "mojo_apps_js_unittests",
+ "mojo_clipboard_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_surfaces_lib_unittests",
+ "mojo_system_unittests",
+ "nacl_loader_unittests"
+ ]
+ },
+ "Linux ARM Cross-Compile": {
+ "compile_targets": [
+ "browser_tests_run"
+ ],
+ "gtest_tests": [
+ "browser_tests"
+ ]
+ },
+ "Chromium Mac 10.10": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "google_apis_unittests",
+ "interactive_ui_tests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "message_center_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_clipboard_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_mac_unittests",
+ "sql_unittests",
+ "sync_integration_tests",
+ "sync_unit_tests",
+ "ui_unittests",
+ "unit_tests",
+ "url_unittests",
+ "browser_tests"
+ ]
+ },
+ "Site Isolation Linux": {
+ "gtest_tests": [
+ { "test": "content_unittests", "args": ["--site-per-process"] },
+ { "test": "content_browsertests", "args": ["--site-per-process"] }
+ ]
+ },
+ "Site Isolation Win": {
+ "gtest_tests": [
+ { "test": "content_unittests", "args": ["--site-per-process"] },
+ { "test": "content_browsertests", "args": ["--site-per-process"] }
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
new file mode 100644
index 0000000..5221109
--- /dev/null
+++ b/testing/buildbot/chromium.linux.json
@@ -0,0 +1,344 @@
+{
+ "Linux Tests": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ "aura_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 5
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "dbus_unittests",
+ "device_unittests",
+ "display_unittests",
+ "events_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ipc_mojo_unittests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "mojo_view_manager_unittests",
+ "nacl_loader_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "ui_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Linux Tests (dbg)(1)(32)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ "aura_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 10
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "dbus_unittests",
+ "device_unittests",
+ "display_unittests",
+ "events_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ipc_mojo_unittests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "mojo_view_manager_unittests",
+ "nacl_loader_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "ui_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Linux Tests (dbg)(2)(32)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux Tests (dbg)(1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ "aura_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 10
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "dbus_unittests",
+ "device_unittests",
+ "display_unittests",
+ "events_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 3
+ }
+ },
+ "ipc_mojo_unittests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "mojo_view_manager_unittests",
+ "nacl_loader_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "ui_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Linux Tests (dbg)(2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux Clang (dbg)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_shell_unittests",
+ "base_unittests",
+ "components_unittests",
+ "content_unittests",
+ "crypto_unittests",
+ "device_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "google_apis_unittests",
+ "ipc_mojo_unittests",
+ "ipc_tests",
+ "mojo_application_manager_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "mojo_view_manager_unittests",
+ "nacl_loader_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ "unit_tests"
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
new file mode 100644
index 0000000..0dcc605
--- /dev/null
+++ b/testing/buildbot/chromium.mac.json
@@ -0,0 +1,289 @@
+{
+ "Mac10.6 Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "google_apis_unittests",
+ "interactive_ui_tests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "message_center_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_mac_unittests",
+ "sql_unittests",
+ "sync_integration_tests",
+ "sync_unit_tests",
+ "ui_unittests",
+ "unit_tests",
+ "url_unittests"
+ ]
+ },
+ "Mac10.6 Tests (2)": {
+ "gtest_tests": [
+ "browser_tests"
+ ]
+ },
+ "Mac10.7 Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 10
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "google_apis_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "message_center_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_mac_unittests",
+ "sql_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests"
+ ]
+ },
+ "Mac10.7 Tests (2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Mac 10.6 Tests (dbg)(1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "google_apis_unittests",
+ "interactive_ui_tests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "message_center_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_mac_unittests",
+ "sql_unittests",
+ "sync_integration_tests",
+ "sync_unit_tests",
+ "ui_unittests",
+ "unit_tests",
+ "url_unittests"
+ ]
+ },
+ "Mac 10.6 Tests (dbg)(2)": {
+ "gtest_tests": [
+ "browser_tests"
+ ]
+ },
+ "Mac 10.7 Tests (dbg)(1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 20
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "google_apis_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "message_center_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_application_manager_unittests",
+ "mojo_shell_tests",
+ "mojo_system_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_mac_unittests",
+ "sql_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests"
+ ]
+ },
+ "Mac 10.7 Tests (dbg)(2)": {
+ "gtest_tests": [
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json
new file mode 100644
index 0000000..1108732
--- /dev/null
+++ b/testing/buildbot/chromium.memory.fyi.json
@@ -0,0 +1,46 @@
+{
+ "Linux MSan Tests": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_shell_browsertests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cc_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "device_unittests",
+ "extensions_unittests",
+ "gpu_unittests",
+ "interactive_ui_tests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ "unit_tests",
+ "url_unittests"
+ ]
+ },
+ "Linux MSan Browser (1)": {
+ "gtest_tests": [
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3}
+ ]
+ },
+ "Linux MSan Browser (2)": {
+ "gtest_tests": [
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "Linux MSan Browser (3)": {
+ "gtest_tests": [
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
new file mode 100644
index 0000000..f26c47a
--- /dev/null
+++ b/testing/buildbot/chromium.memory.json
@@ -0,0 +1,232 @@
+{
+ "Linux ASan LSan Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_shell_browsertests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 5
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "device_unittests",
+ "display_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests"
+ ]
+ },
+ "Linux ASan LSan Tests (2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux ASan LSan Tests (3)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux ASan Tests (sandboxed)": {
+ "gtest_tests": [
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 5
+ }
+ },
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ }
+ ]
+ },
+ "Mac ASan Tests (1)": {
+ "gtest_tests": [
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "gcm_unit_tests",
+ "gpu_unittests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sql_unittests",
+ "url_unittests",
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3}
+ ]
+ },
+ "Mac ASan Tests (2)": {
+ "gtest_tests": [
+ "net_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "Mac ASan Tests (3)": {
+ "gtest_tests": [
+ "interactive_ui_tests",
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
+ },
+ "Mac ASan 64 Tests (1)": {
+ "gtest_tests": [
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "components_unittests",
+ "content_browsertests",
+ "content_unittests",
+ "crypto_unittests",
+ "gcm_unit_tests",
+ "gpu_unittests",
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sql_unittests",
+ "unit_tests",
+ "url_unittests",
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3}
+ ]
+ },
+ "Mac ASan 64 Tests (2)": {
+ "gtest_tests": [
+ "net_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "Mac ASan 64 Tests (3)": {
+ "gtest_tests": [
+ "interactive_ui_tests",
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
+ },
+ "Linux Chromium OS ASan LSan Tests (1)": {
+ "gtest_tests": [
+ "ash_unittests",
+ "aura_unittests",
+ "base_unittests",
+ "cacheinvalidation_unittests",
+ "chromeos_unittests",
+ "compositor_unittests",
+ "content_browsertests",
+ "crypto_unittests",
+ "events_unittests",
+ "gcm_unit_tests",
+ "gpu_unittests",
+ "jingle_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "url_unittests",
+ "views_unittests",
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3}
+ ]
+ },
+ "Linux Chromium OS ASan LSan Tests (2)": {
+ "gtest_tests": [
+ "interactive_ui_tests",
+ "net_unittests",
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "Linux Chromium OS ASan LSan Tests (3)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ "athena_unittests",
+ "cast_unittests",
+ "components_unittests",
+ "content_unittests",
+ "device_unittests",
+ "display_unittests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "ipc_tests",
+ "message_center_unittests",
+ "nacl_loader_unittests",
+ "sandbox_linux_unittests",
+ "sql_unittests",
+ "sync_unittests",
+ "ui_unittests",
+ "unit_tests",
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.webkit.json b/testing/buildbot/chromium.webkit.json
new file mode 100644
index 0000000..b121217
--- /dev/null
+++ b/testing/buildbot/chromium.webkit.json
@@ -0,0 +1,192 @@
+{
+ "Linux ChromiumOS Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 5
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chromeos_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "dbus_unittests",
+ "display_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ {
+ "test": "ash_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "app_list_unittests",
+ "message_center_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sql_unittests",
+ "nacl_loader_unittests",
+ "athena_unittests",
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ "chromevox_tests"
+ ]
+ },
+ "Linux ChromiumOS Tests (2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux ChromiumOS Tests (dbg)(1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chromeos_unittests",
+ "components_unittests",
+ "crypto_unittests",
+ "dbus_unittests",
+ "extensions_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "device_unittests",
+ "display_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sandbox_linux_unittests",
+ "ui_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ {
+ "test": "ash_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "app_list_unittests",
+ "message_center_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sql_unittests",
+ "nacl_loader_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 20
+ }
+ },
+ "app_shell_browsertests",
+ "app_shell_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "athena_unittests",
+ "gcm_unit_tests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 3
+ }
+ }
+ ]
+ },
+ "Linux ChromiumOS Tests (dbg)(2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Linux ChromiumOS Tests (dbg)(3)": {
+ "gtest_tests": [
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
new file mode 100644
index 0000000..e2751cd
--- /dev/null
+++ b/testing/buildbot/chromium.win.json
@@ -0,0 +1,476 @@
+{
+ "XP Tests (1)": {
+ "gtest_tests": [
+ "interactive_ui_tests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3},
+ "content_browsertests",
+ "installer_util_unittests"
+ ]
+ },
+ "XP Tests (2)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "base_unittests",
+ "net_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ "ash_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "sync_integration_tests",
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "XP Tests (3)": {
+ "gtest_tests": [
+ "app_shell_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_unittests",
+ "content_unittests",
+ "views_unittests",
+ "wm_unittests",
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
+ },
+ "Vista Tests (1)": {
+ "gtest_tests": [
+ "interactive_ui_tests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "gfx_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "media_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ {"test": "browser_tests", "shard_index": 0, "total_shards": 3},
+ "content_browsertests",
+ "installer_util_unittests"
+ ]
+ },
+ "Vista Tests (2)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ "base_unittests",
+ "net_unittests",
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ "ash_unittests",
+ "compositor_unittests",
+ "events_unittests",
+ "sync_integration_tests",
+ {"test": "browser_tests", "shard_index": 1, "total_shards": 3}
+ ]
+ },
+ "Vista Tests (3)": {
+ "gtest_tests": [
+ "app_shell_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "ipc_tests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_system_unittests",
+ "sync_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_unittests",
+ "content_unittests",
+ "views_unittests",
+ "wm_unittests",
+ {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
+ ]
+ },
+ "Win7 Tests (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "ash_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "app_shell_unittests",
+ "aura_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 7
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "courgette_unittests",
+ "crypto_unittests",
+ "events_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "installer_util_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_system_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "sql_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Win7 Tests (2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win7 Tests (3)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win 7 Tests x64 (1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 6
+ }
+ },
+ "app_list_unittests",
+ "app_shell_unittests",
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "installer_util_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_system_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "sql_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Win 7 Tests x64 (2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win 7 Tests x64 (3)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win7 Tests (dbg)(1)": {
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "ash_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "app_shell_unittests",
+ "aura_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 20
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "compositor_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "courgette_unittests",
+ "crypto_unittests",
+ "events_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "gpu_unittests",
+ "installer_util_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 4
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ "mojo_system_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "sql_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "url_unittests",
+ "views_unittests",
+ "wm_unittests"
+ ]
+ },
+ "Win7 Tests (dbg)(2)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win7 Tests (dbg)(3)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win7 Tests (dbg)(4)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win7 Tests (dbg)(5)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win7 Tests (dbg)(6)": {
+ "gtest_tests": [
+ ]
+ },
+ "Interactive Tests (dbg)": {
+ "gtest_tests": [
+ ]
+ },
+ "Win8 Aura": {
+ "gtest_tests": [
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ "ash_unittests",
+ "compositor_unittests",
+ "content_browsertests",
+ "events_unittests"
+ ]
+ }
+}
diff --git a/testing/buildbot/chromium_arm.json b/testing/buildbot/chromium_arm.json
new file mode 100644
index 0000000..a2d4329
--- /dev/null
+++ b/testing/buildbot/chromium_arm.json
@@ -0,0 +1,12 @@
+{
+ "compile_targets": [
+ "browser_tests_run",
+ "nacl_loader_unittests_run",
+ "sandbox_linux_unittests_run"
+ ],
+ "gtest_tests": [
+ "browser_tests",
+ "nacl_loader_unittests",
+ "sandbox_linux_unittests"
+ ]
+}
diff --git a/testing/buildbot/chromium_memory_trybot.json b/testing/buildbot/chromium_memory_trybot.json
new file mode 100644
index 0000000..554cbbb
--- /dev/null
+++ b/testing/buildbot/chromium_memory_trybot.json
@@ -0,0 +1,77 @@
+{
+ "gtest_tests": [
+ "accessibility_unittests",
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 10
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cc_unittests",
+ "components_unittests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ "device_unittests",
+ {
+ "test": "display_unittests",
+ "platforms": ["linux"]
+ },
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 3
+ }
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ "media_unittests",
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ {
+ "test": "sandbox_linux_unittests",
+ "platforms": ["linux"]
+ },
+ "sql_unittests",
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "url_unittests"
+ ]
+}
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
new file mode 100644
index 0000000..3078088
--- /dev/null
+++ b/testing/buildbot/chromium_trybot.json
@@ -0,0 +1,233 @@
+{
+ "compile_targets": [
+ "all"
+ ],
+ "gtest_tests": [
+ "accessibility_unittests",
+ "app_list_unittests",
+ {
+ "test": "ash_unittests",
+ "chromium_configs": ["chromium_chromeos", "chromium_chromeos_clang"],
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "ash_unittests",
+ "platforms": ["win"],
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "browser_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 5
+ }
+ },
+ "cacheinvalidation_unittests",
+ "cast_unittests",
+ "cc_unittests",
+ "chromedriver_unittests",
+ {
+ "test": "chromevox_tests",
+ "chromium_configs": ["chromium_chromeos", "chromium_chromeos_clang"]
+ },
+ {
+ "test": "chrome_elf_unittests",
+ "platforms": ["win"]
+ },
+ "components_browsertests",
+ "components_unittests",
+ {
+ "test": "compositor_unittests",
+ "platforms": ["linux", "win"]
+ },
+ {
+ "test": "courgette_unittests",
+ "platforms": ["win"]
+ },
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ {
+ "test": "content_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "crypto_unittests",
+ {
+ "test": "dbus_unittests",
+ "platforms": ["linux"]
+ },
+ "device_unittests",
+ "events_unittests",
+ {
+ "test": "extensions_unittests",
+ "platforms": ["win", "mac", "linux"]
+ },
+ "gcm_unit_tests",
+ "gfx_unittests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ {
+ "test": "interactive_ui_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 3
+ }
+ },
+ {
+ "test": "installer_util_unittests",
+ "platforms": ["win"]
+ },
+ {
+ "test": "ipc_mojo_unittests",
+ "platforms": ["linux"]
+ },
+ "ipc_tests",
+ "jingle_unittests",
+ {
+ "test": "keyboard_unittests",
+ "platforms": ["linux", "win"]
+ },
+ "media_perftests",
+ "media_unittests",
+ "message_center_unittests",
+ "mojo_apps_js_unittests",
+ "mojo_common_unittests",
+ "mojo_js_unittests",
+ "mojo_public_bindings_unittests",
+ "mojo_public_environment_unittests",
+ "mojo_public_system_unittests",
+ "mojo_public_utility_unittests",
+ {
+ "test": "mojo_application_manager_unittests",
+ "platforms": ["linux"]
+ },
+ {
+ "test": "mojo_shell_tests",
+ "platforms": ["linux"]
+ },
+ "mojo_system_unittests",
+ {
+ "test": "nacl_loader_unittests",
+ "platforms": ["linux"]
+ },
+ {
+ "test": "net_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ {
+ "test": "sbox_integration_tests",
+ "platforms": ["win"]
+ },
+ {
+ "test": "sbox_validation_tests",
+ "platforms": ["win"]
+ },
+ {
+ "test": "sbox_unittests",
+ "platforms": ["win"]
+ },
+ "sql_unittests",
+ {
+ "test": "sync_integration_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 3
+ }
+ },
+ "sync_unit_tests",
+ "ui_unittests",
+ {
+ "test": "unit_tests",
+ "swarming": {
+ "can_use_on_swarming_builders": true,
+ "shards": 2
+ }
+ },
+ "url_unittests",
+ {
+ "test": "wm_unittests",
+ "platforms": ["linux"]
+ },
+ {
+ "test": "app_shell_browsertests",
+ "platforms": ["linux"]
+ },
+ {
+ "test": "app_shell_unittests",
+ "platforms": ["linux", "win"]
+ },
+ {
+ "test": "aura_unittests",
+ "platforms": ["linux", "win"]
+ },
+ {
+ "test": "mojo_view_manager_unittests",
+ "platforms": ["linux"]
+ },
+ {
+ "test": "views_unittests",
+ "platforms": ["linux", "win"]
+ },
+ {
+ "test": "sandbox_linux_unittests",
+ "platforms": ["linux"],
+ "args": ["--test-launcher-print-test-stdio=always"]
+ },
+ {
+ "test": "sandbox_mac_unittests",
+ "platforms": ["mac"]
+ },
+ {
+ "test": "chromeos_unittests",
+ "platforms": ["linux"],
+ "chromium_configs": ["chromium_chromeos", "chromium_chromeos_clang"]
+ },
+ {
+ "test": "athena_unittests",
+ "platforms": ["linux"],
+ "chromium_configs": ["chromium_chromeos", "chromium_chromeos_clang"]
+ },
+ {
+ "test": "display_unittests",
+ "platforms": ["linux"]
+ },
+ {
+ "test": "ozone_unittests",
+ "platforms": ["linux"],
+ "chromium_configs": ["chromium_chromeos_ozone"]
+ }
+ ],
+
+ "non_filter_builders": [
+ ],
+
+ "non_filter_tests_builders": [
+ ],
+
+ "filter_compile_builders": [
+ "win_chromium_compile_dbg",
+ "win_chromium_rel_swarming",
+ "win_chromium_x64_rel_swarming",
+ "win8_chromium_rel"
+ ]
+}
diff --git a/testing/buildbot/chromium_win8_trybot.json b/testing/buildbot/chromium_win8_trybot.json
new file mode 100644
index 0000000..e78d41a
--- /dev/null
+++ b/testing/buildbot/chromium_win8_trybot.json
@@ -0,0 +1,14 @@
+{
+ "compile_targets": [
+ "all"
+ ],
+ "gtest_tests": [
+ "views_unittests",
+ "wm_unittests",
+ "aura_unittests",
+ "ash_unittests",
+ "compositor_unittests",
+ "content_browsertests",
+ "events_unittests"
+ ]
+}
diff --git a/testing/buildbot/trybot_analyze_config.json b/testing/buildbot/trybot_analyze_config.json
new file mode 100644
index 0000000..9074b98
--- /dev/null
+++ b/testing/buildbot/trybot_analyze_config.json
@@ -0,0 +1,37 @@
+{
+ "base": {
+ "exclusions": [
+ ".\\.isolate",
+ "build/.*gyp[i]?",
+ "build/android/pylib/.*",
+ "build/compiler_version.py",
+ "build/get_landmines.py",
+ "build/gyp_chromium",
+ "build/linux/sysroot_ld_path.sh",
+ "DEPS",
+ "testing/buildbot/.*",
+ "tools/clang/blink_gc_plugin/CMakeLists.txt",
+ "tools/whitespace.txt"
+ ]
+ },
+ "android_webview": {
+ "exclusions": [
+ "android_webview/.*"
+ ]
+ },
+ "chromium": {
+ "exclusions": [
+ "chrome/test/data/.*",
+ "content/test/data/.*",
+ "content/test/gpu/.*",
+ "gpu/gles2_conform_support/gles2_conform_test_expectations.txt",
+ "net/data/.*",
+ "tools/clang/scripts/plugin_flags.sh",
+ "tools/clang/scripts/update.py",
+ "tools/clang/scripts/update.sh",
+ "tools/metrics/histograms/histograms.xml",
+ "tools/perf/.*",
+ "tools/telemetry/.*"
+ ]
+ }
+}
diff --git a/testing/buildbot/tryserver.chromium.linux.json b/testing/buildbot/tryserver.chromium.linux.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/testing/buildbot/tryserver.chromium.linux.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/testing/buildbot/tryserver.chromium.mac.json b/testing/buildbot/tryserver.chromium.mac.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/testing/buildbot/tryserver.chromium.mac.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/testing/buildbot/tryserver.chromium.win.json b/testing/buildbot/tryserver.chromium.win.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/testing/buildbot/tryserver.chromium.win.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/testing/chromoting/chromoting_integration_tests.isolate b/testing/chromoting/chromoting_integration_tests.isolate
new file mode 100644
index 0000000..4b45213
--- /dev/null
+++ b/testing/chromoting/chromoting_integration_tests.isolate
@@ -0,0 +1,69 @@
+# Copyright (c) 2014 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.
+{
+ 'conditions': [
+ ['OS=="linux"', {
+ 'variables': {
+ 'command': [
+ '../xvfb.py',
+ '<(PRODUCT_DIR)',
+ '<(PRODUCT_DIR)/browser_tests<(EXECUTABLE_SUFFIX)',
+ '--gtest_filter=RemoteDesktopBrowserTest.MANUAL_Launch',
+ '--run-manual',
+ '--ui-test-action-timeout=100000',
+ '--webapp-unpacked=<(PRODUCT_DIR)/remoting/remoting.webapp',
+ '--extension-name=Chromoting',
+ ],
+ 'files': [
+ '../xvfb.py',
+ '<(PRODUCT_DIR)/libffmpegsumo.so',
+ '<(PRODUCT_DIR)/libosmesa.so',
+ '<(PRODUCT_DIR)/nacl_irt_x86_64.nexe',
+ ],
+ },
+ }],
+ ['OS=="linux" and use_ozone==0', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)',
+ ],
+ },
+ }],
+ ['OS=="linux" or OS=="mac" or OS=="win"', {
+ 'variables': {
+ 'files': [
+ '../test_env.py',
+ '<(PRODUCT_DIR)/browser_tests<(EXECUTABLE_SUFFIX)',
+ '<(PRODUCT_DIR)/remoting/remoting.webapp/',
+ '<(PRODUCT_DIR)/resources.pak',
+ ],
+ 'read_only': 1,
+ },
+ }],
+ ['OS=="linux" or OS=="win"', {
+ 'variables': {
+ 'files': [
+ '<(PRODUCT_DIR)/chrome_100_percent.pak',
+ '<(PRODUCT_DIR)/locales/en-US.pak',
+ ],
+ },
+ }],
+ ['OS=="mac" or OS=="win"', {
+ 'variables': {
+ 'command': [
+ '../testing/test_env.py',
+ '<(PRODUCT_DIR)/browser_tests<(EXECUTABLE_SUFFIX)',
+ '--gtest_filter=RemoteDesktopBrowserTest.MANUAL_Launch',
+ '--run-manual',
+ '--ui-test-action-timeout=100000',
+ '--webapp-unpacked=<(PRODUCT_DIR)/remoting/remoting.webapp',
+ '--extension-name=Chromoting',
+ ],
+ },
+ }],
+ ],
+ 'includes': [
+ '../../base/base.isolate',
+ ],
+}
diff --git a/testing/chromoting/integration_tests.gyp b/testing/chromoting/integration_tests.gyp
new file mode 100644
index 0000000..b6c801d
--- /dev/null
+++ b/testing/chromoting/integration_tests.gyp
@@ -0,0 +1,26 @@
+# Copyright (c) 2014 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.
+
+{
+ 'conditions': [
+ ['archive_chromoting_tests==1', {
+ 'targets': [
+ {
+ 'target_name': 'chromoting_integration_tests_run',
+ 'type': 'none',
+ 'dependencies': [
+ '../../chrome/chrome.gyp:browser_tests',
+ '../../remoting/remoting.gyp:remoting_webapp_v1',
+ ],
+ 'includes': [
+ '../../build/isolate.gypi',
+ ],
+ 'sources': [
+ 'chromoting_integration_tests.isolate',
+ ],
+ },
+ ],
+ }],
+ ],
+}
diff --git a/testing/coverage_util_ios.cc b/testing/coverage_util_ios.cc
new file mode 100644
index 0000000..15ac1b4
--- /dev/null
+++ b/testing/coverage_util_ios.cc
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+extern "C" void __gcov_flush();
+
+namespace coverage_util {
+
+void FlushCoverageDataIfNecessary() {
+#if defined(ENABLE_TEST_CODE_COVERAGE)
+ __gcov_flush();
+#endif
+}
+
+} // namespace coverage_util
diff --git a/testing/coverage_util_ios.h b/testing/coverage_util_ios.h
new file mode 100644
index 0000000..702811a
--- /dev/null
+++ b/testing/coverage_util_ios.h
@@ -0,0 +1,17 @@
+// Copyright 2014 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.
+
+#ifndef TESTING_COVERAGE_UTIL_IOS_H_
+#define TESTING_COVERAGE_UTIL_IOS_H_
+
+namespace coverage_util {
+
+// Flushes .gcda coverage files if ENABLE_TEST_CODE_COVERAGE is defined. iOS 7
+// does not call any code at the "end" of an app so flushing should be
+// performed manually.
+void FlushCoverageDataIfNecessary();
+
+} // namespace coverage_util
+
+#endif // TESTING_COVERAGE_UTIL_IOS_H_
diff --git a/testing/generate_gmock_mutant.py b/testing/generate_gmock_mutant.py
new file mode 100755
index 0000000..6d814f0
--- /dev/null
+++ b/testing/generate_gmock_mutant.py
@@ -0,0 +1,457 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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 string
+import sys
+
+HEADER = """\
+// Copyright (c) 2013 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.
+
+// This file automatically generated by testing/generate_gmock_mutant.py.
+// DO NOT EDIT.
+
+#ifndef TESTING_GMOCK_MUTANT_H_
+#define TESTING_GMOCK_MUTANT_H_
+
+// The intention of this file is to make possible using GMock actions in
+// all of its syntactic beauty. Classes and helper functions can be used as
+// more generic variants of Task and Callback classes (see base/task.h)
+// Mutant supports both pre-bound arguments (like Task) and call-time
+// arguments (like Callback) - hence the name. :-)
+//
+// DispatchToMethod/Function supports two sets of arguments: pre-bound (P) and
+// call-time (C). The arguments as well as the return type are templatized.
+// DispatchToMethod/Function will also try to call the selected method or
+// function even if provided pre-bound arguments does not match exactly with
+// the function signature hence the X1, X2 ... XN parameters in CreateFunctor.
+// DispatchToMethod will try to invoke method that may not belong to the
+// object's class itself but to the object's class base class.
+//
+// Additionally you can bind the object at calltime by binding a pointer to
+// pointer to the object at creation time - before including this file you
+// have to #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING.
+//
+// TODO(stoyan): It's yet not clear to me should we use T& and T&* instead
+// of T* and T** when we invoke CreateFunctor to match the EXPECT_CALL style.
+//
+//
+// Sample usage with gMock:
+//
+// struct Mock : public ObjectDelegate {
+// MOCK_METHOD2(string, OnRequest(int n, const string& request));
+// MOCK_METHOD1(void, OnQuit(int exit_code));
+// MOCK_METHOD2(void, LogMessage(int level, const string& message));
+//
+// string HandleFlowers(const string& reply, int n, const string& request) {
+// string result = SStringPrintf("In request of %d %s ", n, request);
+// for (int i = 0; i < n; ++i) result.append(reply)
+// return result;
+// }
+//
+// void DoLogMessage(int level, const string& message) {
+// }
+//
+// void QuitMessageLoop(int seconds) {
+// MessageLoop* loop = MessageLoop::current();
+// loop->PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
+// 1000 * seconds);
+// }
+// };
+//
+// Mock mock;
+// // Will invoke mock.HandleFlowers("orchids", n, request)
+// // "orchids" is a pre-bound argument, and <n> and <request> are call-time
+// // arguments - they are not known until the OnRequest mock is invoked.
+// EXPECT_CALL(mock, OnRequest(Ge(5), StartsWith("flower"))
+// .Times(1)
+// .WillOnce(Invoke(CreateFunctor(&mock, &Mock::HandleFlowers,
+// string("orchids"))));
+//
+//
+// // No pre-bound arguments, two call-time arguments passed
+// // directly to DoLogMessage
+// EXPECT_CALL(mock, OnLogMessage(_, _))
+// .Times(AnyNumber())
+// .WillAlways(Invoke(CreateFunctor, &mock, &Mock::DoLogMessage));
+//
+//
+// // In this case we have a single pre-bound argument - 3. We ignore
+// // all of the arguments of OnQuit.
+// EXCEPT_CALL(mock, OnQuit(_))
+// .Times(1)
+// .WillOnce(InvokeWithoutArgs(CreateFunctor(
+// &mock, &Mock::QuitMessageLoop, 3)));
+//
+// MessageLoop loop;
+// loop.Run();
+//
+//
+// // Here is another example of how we can set an action that invokes
+// // method of an object that is not yet created.
+// struct Mock : public ObjectDelegate {
+// MOCK_METHOD1(void, DemiurgeCreated(Demiurge*));
+// MOCK_METHOD2(void, OnRequest(int count, const string&));
+//
+// void StoreDemiurge(Demiurge* w) {
+// demiurge_ = w;
+// }
+//
+// Demiurge* demiurge;
+// }
+//
+// EXPECT_CALL(mock, DemiurgeCreated(_)).Times(1)
+// .WillOnce(Invoke(CreateFunctor(&mock, &Mock::StoreDemiurge)));
+//
+// EXPECT_CALL(mock, OnRequest(_, StrEq("Moby Dick")))
+// .Times(AnyNumber())
+// .WillAlways(WithArgs<0>(Invoke(
+// CreateFunctor(&mock->demiurge_, &Demiurge::DecreaseMonsters))));
+//
+
+#include "base/memory/linked_ptr.h"
+#include "base/tuple.h" // for Tuple
+
+namespace testing {"""
+
+MUTANT = """\
+
+// Interface that is exposed to the consumer, that does the actual calling
+// of the method.
+template <typename R, typename Params>
+class MutantRunner {
+ public:
+ virtual R RunWithParams(const Params& params) = 0;
+ virtual ~MutantRunner() {}
+};
+
+// Mutant holds pre-bound arguments (like Task). Like Callback
+// allows call-time arguments. You bind a pointer to the object
+// at creation time.
+template <typename R, typename T, typename Method,
+ typename PreBound, typename Params>
+class Mutant : public MutantRunner<R, Params> {
+ public:
+ Mutant(T* obj, Method method, const PreBound& pb)
+ : obj_(obj), method_(method), pb_(pb) {
+ }
+
+ // MutantRunner implementation
+ virtual R RunWithParams(const Params& params) {
+ return DispatchToMethod<R>(this->obj_, this->method_, pb_, params);
+ }
+
+ T* obj_;
+ Method method_;
+ PreBound pb_;
+};
+
+template <typename R, typename Function, typename PreBound, typename Params>
+class MutantFunction : public MutantRunner<R, Params> {
+ public:
+ MutantFunction(Function function, const PreBound& pb)
+ : function_(function), pb_(pb) {
+ }
+
+ // MutantRunner implementation
+ virtual R RunWithParams(const Params& params) {
+ return DispatchToFunction<R>(function_, pb_, params);
+ }
+
+ Function function_;
+ PreBound pb_;
+};
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+// MutantLateBind is like Mutant, but you bind a pointer to a pointer
+// to the object. This way you can create actions for an object
+// that is not yet created (has only storage for a pointer to it).
+template <typename R, typename T, typename Method,
+ typename PreBound, typename Params>
+class MutantLateObjectBind : public MutantRunner<R, Params> {
+ public:
+ MutantLateObjectBind(T** obj, Method method, const PreBound& pb)
+ : obj_(obj), method_(method), pb_(pb) {
+ }
+
+ // MutantRunner implementation.
+ virtual R RunWithParams(const Params& params) {
+ EXPECT_THAT(*this->obj_, testing::NotNull());
+ if (NULL == *this->obj_)
+ return R();
+ return DispatchToMethod<R>( *this->obj_, this->method_, pb_, params);
+ }
+
+ T** obj_;
+ Method method_;
+ PreBound pb_;
+};
+#endif
+
+// Simple MutantRunner<> wrapper acting as a functor.
+// Redirects operator() to MutantRunner<Params>::Run()
+template <typename R, typename Params>
+struct MutantFunctor {
+ explicit MutantFunctor(MutantRunner<R, Params>* cb) : impl_(cb) {
+ }
+
+ ~MutantFunctor() {
+ }
+
+ inline R operator()() {
+ return impl_->RunWithParams(Tuple0());
+ }
+
+ template <typename Arg1>
+ inline R operator()(const Arg1& a) {
+ return impl_->RunWithParams(Params(a));
+ }
+
+ template <typename Arg1, typename Arg2>
+ inline R operator()(const Arg1& a, const Arg2& b) {
+ return impl_->RunWithParams(Params(a, b));
+ }
+
+ template <typename Arg1, typename Arg2, typename Arg3>
+ inline R operator()(const Arg1& a, const Arg2& b, const Arg3& c) {
+ return impl_->RunWithParams(Params(a, b, c));
+ }
+
+ template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+ inline R operator()(const Arg1& a, const Arg2& b, const Arg3& c,
+ const Arg4& d) {
+ return impl_->RunWithParams(Params(a, b, c, d));
+ }
+
+ private:
+ // We need copy constructor since MutantFunctor is copied few times
+ // inside GMock machinery, hence no DISALLOW_EVIL_CONTRUCTORS
+ MutantFunctor();
+ linked_ptr<MutantRunner<R, Params> > impl_;
+};
+"""
+
+FOOTER = """\
+} // namespace testing
+
+#endif // TESTING_GMOCK_MUTANT_H_"""
+
+# Templates for DispatchToMethod/DispatchToFunction functions.
+# template_params - typename P1, typename P2.. typename C1..
+# prebound - TupleN<P1, .. PN>
+# calltime - TupleN<C1, .. CN>
+# args - p.a, p.b.., c.a, c.b..
+DISPATCH_TO_METHOD_TEMPLATE = """\
+template <typename R, typename T, typename Method, %(template_params)s>
+inline R DispatchToMethod(T* obj, Method method,
+ const %(prebound)s& p,
+ const %(calltime)s& c) {
+ return (obj->*method)(%(args)s);
+}
+"""
+
+DISPATCH_TO_FUNCTION_TEMPLATE = """\
+template <typename R, typename Function, %(template_params)s>
+inline R DispatchToFunction(Function function,
+ const %(prebound)s& p,
+ const %(calltime)s& c) {
+ return (*function)(%(args)s);
+}
+"""
+
+# Templates for CreateFunctor functions.
+# template_params - typename P1, typename P2.. typename C1.. typename X1..
+# prebound - TupleN<P1, .. PN>
+# calltime - TupleN<A1, .. AN>
+# params - X1,.. , A1, ..
+# args - const P1& p1 ..
+# call_args - p1, p2, p3..
+CREATE_METHOD_FUNCTOR_TEMPLATE = """\
+template <typename R, typename T, typename U, %(template_params)s>
+inline MutantFunctor<R, %(calltime)s>
+CreateFunctor(T* obj, R (U::*method)(%(params)s), %(args)s) {
+ MutantRunner<R, %(calltime)s>* t =
+ new Mutant<R, T, R (U::*)(%(params)s),
+ %(prebound)s, %(calltime)s>
+ (obj, method, MakeTuple(%(call_args)s));
+ return MutantFunctor<R, %(calltime)s>(t);
+}
+"""
+
+CREATE_FUNCTION_FUNCTOR_TEMPLATE = """\
+template <typename R, %(template_params)s>
+inline MutantFunctor<R, %(calltime)s>
+CreateFunctor(R (*function)(%(params)s), %(args)s) {
+ MutantRunner<R, %(calltime)s>* t =
+ new MutantFunction<R, R (*)(%(params)s),
+ %(prebound)s, %(calltime)s>
+ (function, MakeTuple(%(call_args)s));
+ return MutantFunctor<R, %(calltime)s>(t);
+}
+"""
+
+def SplitLine(line, width):
+ """Splits a single line at comma, at most |width| characters long."""
+ if len(line) < width:
+ return (line, None)
+ n = 1 + line[:width].rfind(",")
+ if n == 0: # If comma cannot be found give up and return the entire line.
+ return (line, None)
+ # Assume there is a space after the comma
+ assert line[n] == " "
+ return (line[:n], line[n + 1:])
+
+
+def Wrap(s, width, subsequent_offset=4):
+ """Wraps a single line |s| at commas so every line is at most |width|
+ characters long.
+ """
+ w = []
+ spaces = " " * subsequent_offset
+ while s:
+ (f, s) = SplitLine(s, width)
+ w.append(f)
+ if s:
+ s = spaces + s
+ return "\n".join(w)
+
+
+def Clean(s):
+ """Cleans artifacts from generated C++ code.
+
+ Our simple string formatting/concatenation may introduce extra commas.
+ """
+ s = s.replace("<>", "")
+ s = s.replace(", >", ">")
+ s = s.replace(", )", ")")
+ s = s.replace(">>", "> >")
+ return s
+
+
+def ExpandPattern(pattern, it):
+ """Return list of expanded pattern strings.
+
+ Each string is created by replacing all '%' in |pattern| with element of |it|.
+ """
+ return [pattern.replace("%", x) for x in it]
+
+
+def Gen(pattern, n):
+ """Expands pattern replacing '%' with sequential integers.
+
+ Expanded patterns will be joined with comma separator.
+ GenAlphs("X%", 3) will return "X1, X2, X3".
+ """
+ it = string.hexdigits[1:n + 1]
+ return ", ".join(ExpandPattern(pattern, it))
+
+
+def GenAlpha(pattern, n):
+ """Expands pattern replacing '%' with sequential small ASCII letters.
+
+ Expanded patterns will be joined with comma separator.
+ GenAlphs("X%", 3) will return "Xa, Xb, Xc".
+ """
+ it = string.ascii_lowercase[0:n]
+ return ", ".join(ExpandPattern(pattern, it))
+
+
+def Merge(a):
+ return ", ".join(filter(len, a))
+
+
+def GenTuple(pattern, n):
+ return Clean("Tuple%d<%s>" % (n, Gen(pattern, n)))
+
+
+def FixCode(s):
+ lines = Clean(s).splitlines()
+ # Wrap sometimes very long 1st and 3rd line at 80th column.
+ lines[0] = Wrap(lines[0], 80, 10)
+ lines[2] = Wrap(lines[2], 80, 4)
+ return "\n".join(lines)
+
+
+def GenerateDispatch(prebound, calltime):
+ print "\n// %d - %d" % (prebound, calltime)
+ args = {
+ "template_params": Merge([Gen("typename P%", prebound),
+ Gen("typename C%", calltime)]),
+ "prebound": GenTuple("P%", prebound),
+ "calltime": GenTuple("C%", calltime),
+ "args": Merge([GenAlpha("p.%", prebound), GenAlpha("c.%", calltime)]),
+ }
+
+ print FixCode(DISPATCH_TO_METHOD_TEMPLATE % args)
+ print FixCode(DISPATCH_TO_FUNCTION_TEMPLATE % args)
+
+
+def GenerateCreateFunctor(prebound, calltime):
+ print "// %d - %d" % (prebound, calltime)
+ args = {
+ "calltime": GenTuple("A%", calltime),
+ "prebound": GenTuple("P%", prebound),
+ "params": Merge([Gen("X%", prebound), Gen("A%", calltime)]),
+ "args": Gen("const P%& p%", prebound),
+ "call_args": Gen("p%", prebound),
+ "template_params": Merge([Gen("typename P%", prebound),
+ Gen("typename A%", calltime),
+ Gen("typename X%", prebound)])
+ }
+
+ mutant = FixCode(CREATE_METHOD_FUNCTOR_TEMPLATE % args)
+ print mutant
+
+ # Slightly different version for free function call.
+ print "\n", FixCode(CREATE_FUNCTION_FUNCTOR_TEMPLATE % args)
+
+ # Functor with pointer to a pointer of the object.
+ print "\n#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING"
+ mutant2 = mutant.replace("CreateFunctor(T* obj,", "CreateFunctor(T** obj,")
+ mutant2 = mutant2.replace("new Mutant", "new MutantLateObjectBind")
+ mutant2 = mutant2.replace(" " * 17 + "Tuple", " " * 31 + "Tuple")
+ print mutant2
+ print "#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING\n"
+
+ # OS_WIN specific. Same functors but with stdcall calling conventions.
+ # These are not for WIN64 (x86_64) because there is only one calling
+ # convention in WIN64.
+ # Functor for method with __stdcall calling conventions.
+ print "#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)"
+ stdcall_method = CREATE_METHOD_FUNCTOR_TEMPLATE
+ stdcall_method = stdcall_method.replace("U::", "__stdcall U::")
+ stdcall_method = FixCode(stdcall_method % args)
+ print stdcall_method
+ # Functor for free function with __stdcall calling conventions.
+ stdcall_function = CREATE_FUNCTION_FUNCTOR_TEMPLATE
+ stdcall_function = stdcall_function.replace("R (*", "R (__stdcall *")
+ print "\n", FixCode(stdcall_function % args)
+
+ print "#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING"
+ stdcall2 = stdcall_method
+ stdcall2 = stdcall2.replace("CreateFunctor(T* obj,", "CreateFunctor(T** obj,")
+ stdcall2 = stdcall2.replace("new Mutant", "new MutantLateObjectBind")
+ stdcall2 = stdcall2.replace(" " * 17 + "Tuple", " " * 31 + "Tuple")
+ print stdcall2
+ print "#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING"
+ print "#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)\n"
+
+
+def main():
+ print HEADER
+ for prebound in xrange(0, 6 + 1):
+ for args in xrange(0, 6 + 1):
+ GenerateDispatch(prebound, args)
+ print MUTANT
+ for prebound in xrange(0, 6 + 1):
+ for args in xrange(0, 6 + 1):
+ GenerateCreateFunctor(prebound, args)
+ print FOOTER
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/testing/gmock.gyp b/testing/gmock.gyp
new file mode 100644
index 0000000..22a1893
--- /dev/null
+++ b/testing/gmock.gyp
@@ -0,0 +1,62 @@
+# Copyright (c) 2009 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.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'gmock',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'gtest.gyp:gtest',
+ ],
+ 'sources': [
+ # Sources based on files in r173 of gmock.
+ 'gmock/include/gmock/gmock-actions.h',
+ 'gmock/include/gmock/gmock-cardinalities.h',
+ 'gmock/include/gmock/gmock-generated-actions.h',
+ 'gmock/include/gmock/gmock-generated-function-mockers.h',
+ 'gmock/include/gmock/gmock-generated-matchers.h',
+ 'gmock/include/gmock/gmock-generated-nice-strict.h',
+ 'gmock/include/gmock/gmock-matchers.h',
+ 'gmock/include/gmock/gmock-spec-builders.h',
+ 'gmock/include/gmock/gmock.h',
+ 'gmock/include/gmock/internal/gmock-generated-internal-utils.h',
+ 'gmock/include/gmock/internal/gmock-internal-utils.h',
+ 'gmock/include/gmock/internal/gmock-port.h',
+ 'gmock/src/gmock-all.cc',
+ 'gmock/src/gmock-cardinalities.cc',
+ 'gmock/src/gmock-internal-utils.cc',
+ 'gmock/src/gmock-matchers.cc',
+ 'gmock/src/gmock-spec-builders.cc',
+ 'gmock/src/gmock.cc',
+ 'gmock_mutant.h', # gMock helpers
+ ],
+ 'sources!': [
+ 'gmock/src/gmock-all.cc', # Not needed by our build.
+ ],
+ 'include_dirs': [
+ 'gmock',
+ 'gmock/include',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ 'gmock/include', # So that gmock headers can find themselves.
+ ],
+ },
+ 'export_dependent_settings': [
+ 'gtest.gyp:gtest',
+ ],
+ },
+ {
+ 'target_name': 'gmock_main',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'gmock',
+ ],
+ 'sources': [
+ 'gmock/src/gmock_main.cc',
+ ],
+ },
+ ],
+}
diff --git a/testing/gmock_mutant.h b/testing/gmock_mutant.h
new file mode 100644
index 0000000..90d303e
--- /dev/null
+++ b/testing/gmock_mutant.h
@@ -0,0 +1,4995 @@
+// Copyright (c) 2013 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.
+
+// This file automatically generated by testing/generate_gmock_mutant.py.
+// DO NOT EDIT.
+
+#ifndef TESTING_GMOCK_MUTANT_H_
+#define TESTING_GMOCK_MUTANT_H_
+
+// The intention of this file is to make possible using GMock actions in
+// all of its syntactic beauty. Classes and helper functions can be used as
+// more generic variants of Task and Callback classes (see base/task.h)
+// Mutant supports both pre-bound arguments (like Task) and call-time
+// arguments (like Callback) - hence the name. :-)
+//
+// DispatchToMethod/Function supports two sets of arguments: pre-bound (P) and
+// call-time (C). The arguments as well as the return type are templatized.
+// DispatchToMethod/Function will also try to call the selected method or
+// function even if provided pre-bound arguments does not match exactly with
+// the function signature hence the X1, X2 ... XN parameters in CreateFunctor.
+// DispatchToMethod will try to invoke method that may not belong to the
+// object's class itself but to the object's class base class.
+//
+// Additionally you can bind the object at calltime by binding a pointer to
+// pointer to the object at creation time - before including this file you
+// have to #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING.
+//
+// TODO(stoyan): It's yet not clear to me should we use T& and T&* instead
+// of T* and T** when we invoke CreateFunctor to match the EXPECT_CALL style.
+//
+//
+// Sample usage with gMock:
+//
+// struct Mock : public ObjectDelegate {
+// MOCK_METHOD2(string, OnRequest(int n, const string& request));
+// MOCK_METHOD1(void, OnQuit(int exit_code));
+// MOCK_METHOD2(void, LogMessage(int level, const string& message));
+//
+// string HandleFlowers(const string& reply, int n, const string& request) {
+// string result = SStringPrintf("In request of %d %s ", n, request);
+// for (int i = 0; i < n; ++i) result.append(reply)
+// return result;
+// }
+//
+// void DoLogMessage(int level, const string& message) {
+// }
+//
+// void QuitMessageLoop(int seconds) {
+// base::MessageLoop* loop = base::MessageLoop::current();
+// loop->PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
+// 1000 * seconds);
+// }
+// };
+//
+// Mock mock;
+// // Will invoke mock.HandleFlowers("orchids", n, request)
+// // "orchids" is a pre-bound argument, and <n> and <request> are call-time
+// // arguments - they are not known until the OnRequest mock is invoked.
+// EXPECT_CALL(mock, OnRequest(Ge(5), StartsWith("flower"))
+// .Times(1)
+// .WillOnce(Invoke(CreateFunctor(&mock, &Mock::HandleFlowers,
+// string("orchids"))));
+//
+//
+// // No pre-bound arguments, two call-time arguments passed
+// // directly to DoLogMessage
+// EXPECT_CALL(mock, OnLogMessage(_, _))
+// .Times(AnyNumber())
+// .WillAlways(Invoke(CreateFunctor, &mock, &Mock::DoLogMessage));
+//
+//
+// // In this case we have a single pre-bound argument - 3. We ignore
+// // all of the arguments of OnQuit.
+// EXCEPT_CALL(mock, OnQuit(_))
+// .Times(1)
+// .WillOnce(InvokeWithoutArgs(CreateFunctor(
+// &mock, &Mock::QuitMessageLoop, 3)));
+//
+// MessageLoop loop;
+// loop.Run();
+//
+//
+// // Here is another example of how we can set an action that invokes
+// // method of an object that is not yet created.
+// struct Mock : public ObjectDelegate {
+// MOCK_METHOD1(void, DemiurgeCreated(Demiurge*));
+// MOCK_METHOD2(void, OnRequest(int count, const string&));
+//
+// void StoreDemiurge(Demiurge* w) {
+// demiurge_ = w;
+// }
+//
+// Demiurge* demiurge;
+// }
+//
+// EXPECT_CALL(mock, DemiurgeCreated(_)).Times(1)
+// .WillOnce(Invoke(CreateFunctor(&mock, &Mock::StoreDemiurge)));
+//
+// EXPECT_CALL(mock, OnRequest(_, StrEq("Moby Dick")))
+// .Times(AnyNumber())
+// .WillAlways(WithArgs<0>(Invoke(
+// CreateFunctor(&mock->demiurge_, &Demiurge::DecreaseMonsters))));
+//
+
+#include "base/memory/linked_ptr.h"
+#include "base/tuple.h" // for Tuple
+
+namespace testing {
+
+// 0 - 0
+template <typename R, typename T, typename Method>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple0& c) {
+ return (obj->*method)();
+}
+template <typename R, typename Function>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple0& c) {
+ return (*function)();
+}
+
+// 0 - 1
+template <typename R, typename T, typename Method, typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(c.a);
+}
+template <typename R, typename Function, typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple1<C1>& c) {
+ return (*function)(c.a);
+}
+
+// 0 - 2
+template <typename R, typename T, typename Method, typename C1, typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(c.a, c.b);
+}
+template <typename R, typename Function, typename C1, typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(c.a, c.b);
+}
+
+// 0 - 3
+template <typename R, typename T, typename Method, typename C1, typename C2,
+ typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename C1, typename C2, typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(c.a, c.b, c.c);
+}
+
+// 0 - 4
+template <typename R, typename T, typename Method, typename C1, typename C2,
+ typename C3, typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename C1, typename C2, typename C3,
+ typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(c.a, c.b, c.c, c.d);
+}
+
+// 0 - 5
+template <typename R, typename T, typename Method, typename C1, typename C2,
+ typename C3, typename C4, typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename C1, typename C2, typename C3,
+ typename C4, typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(c.a, c.b, c.c, c.d, c.e);
+}
+
+// 0 - 6
+template <typename R, typename T, typename Method, typename C1, typename C2,
+ typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple0& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename C1, typename C2, typename C3,
+ typename C4, typename C5, typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple0& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// 1 - 0
+template <typename R, typename T, typename Method, typename P1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple0& c) {
+ return (obj->*method)(p.a);
+}
+template <typename R, typename Function, typename P1>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple0& c) {
+ return (*function)(p.a);
+}
+
+// 1 - 1
+template <typename R, typename T, typename Method, typename P1, typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(p.a, c.a);
+}
+template <typename R, typename Function, typename P1, typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple1<C1>& c) {
+ return (*function)(p.a, c.a);
+}
+
+// 1 - 2
+template <typename R, typename T, typename Method, typename P1, typename C1,
+ typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(p.a, c.a, c.b);
+}
+template <typename R, typename Function, typename P1, typename C1, typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(p.a, c.a, c.b);
+}
+
+// 1 - 3
+template <typename R, typename T, typename Method, typename P1, typename C1,
+ typename C2, typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(p.a, c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename P1, typename C1, typename C2,
+ typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(p.a, c.a, c.b, c.c);
+}
+
+// 1 - 4
+template <typename R, typename T, typename Method, typename P1, typename C1,
+ typename C2, typename C3, typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(p.a, c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename P1, typename C1, typename C2,
+ typename C3, typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(p.a, c.a, c.b, c.c, c.d);
+}
+
+// 1 - 5
+template <typename R, typename T, typename Method, typename P1, typename C1,
+ typename C2, typename C3, typename C4, typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(p.a, c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename P1, typename C1, typename C2,
+ typename C3, typename C4, typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(p.a, c.a, c.b, c.c, c.d, c.e);
+}
+
+// 1 - 6
+template <typename R, typename T, typename Method, typename P1, typename C1,
+ typename C2, typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple1<P1>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(p.a, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename P1, typename C1, typename C2,
+ typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple1<P1>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(p.a, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// 2 - 0
+template <typename R, typename T, typename Method, typename P1, typename P2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple0& c) {
+ return (obj->*method)(p.a, p.b);
+}
+template <typename R, typename Function, typename P1, typename P2>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple0& c) {
+ return (*function)(p.a, p.b);
+}
+
+// 2 - 1
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(p.a, p.b, c.a);
+}
+template <typename R, typename Function, typename P1, typename P2, typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple1<C1>& c) {
+ return (*function)(p.a, p.b, c.a);
+}
+
+// 2 - 2
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename C1, typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(p.a, p.b, c.a, c.b);
+}
+template <typename R, typename Function, typename P1, typename P2, typename C1,
+ typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(p.a, p.b, c.a, c.b);
+}
+
+// 2 - 3
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename C1, typename C2, typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(p.a, p.b, c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename P1, typename P2, typename C1,
+ typename C2, typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(p.a, p.b, c.a, c.b, c.c);
+}
+
+// 2 - 4
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename C1, typename C2, typename C3, typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(p.a, p.b, c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename P1, typename P2, typename C1,
+ typename C2, typename C3, typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(p.a, p.b, c.a, c.b, c.c, c.d);
+}
+
+// 2 - 5
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename C1, typename C2, typename C3, typename C4, typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(p.a, p.b, c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename P1, typename P2, typename C1,
+ typename C2, typename C3, typename C4, typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(p.a, p.b, c.a, c.b, c.c, c.d, c.e);
+}
+
+// 2 - 6
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename C1, typename C2, typename C3, typename C4, typename C5,
+ typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple2<P1, P2>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(p.a, p.b, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename P1, typename P2, typename C1,
+ typename C2, typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple2<P1, P2>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(p.a, p.b, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// 3 - 0
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple0& c) {
+ return (obj->*method)(p.a, p.b, p.c);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple0& c) {
+ return (*function)(p.a, p.b, p.c);
+}
+
+// 3 - 1
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(p.a, p.b, p.c, c.a);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple1<C1>& c) {
+ return (*function)(p.a, p.b, p.c, c.a);
+}
+
+// 3 - 2
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename C1, typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(p.a, p.b, p.c, c.a, c.b);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename C1, typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(p.a, p.b, p.c, c.a, c.b);
+}
+
+// 3 - 3
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename C1, typename C2, typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename C1, typename C2, typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(p.a, p.b, p.c, c.a, c.b, c.c);
+}
+
+// 3 - 4
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename C1, typename C2, typename C3, typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename C1, typename C2, typename C3, typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(p.a, p.b, p.c, c.a, c.b, c.c, c.d);
+}
+
+// 3 - 5
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename C1, typename C2, typename C3, typename C4,
+ typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename C1, typename C2, typename C3, typename C4, typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(p.a, p.b, p.c, c.a, c.b, c.c, c.d, c.e);
+}
+
+// 3 - 6
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename C1, typename C2, typename C3, typename C4,
+ typename C5, typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(p.a, p.b, p.c, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename C1, typename C2, typename C3, typename C4, typename C5,
+ typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple3<P1, P2, P3>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(p.a, p.b, p.c, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// 4 - 0
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple0& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple0& c) {
+ return (*function)(p.a, p.b, p.c, p.d);
+}
+
+// 4 - 1
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, c.a);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple1<C1>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, c.a);
+}
+
+// 4 - 2
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename C1, typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename C1, typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, c.a, c.b);
+}
+
+// 4 - 3
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename C1, typename C2, typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename C1, typename C2, typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, c.a, c.b, c.c);
+}
+
+// 4 - 4
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename C1, typename C2, typename C3,
+ typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename C1, typename C2, typename C3, typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d);
+}
+
+// 4 - 5
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename C1, typename C2, typename C3,
+ typename C4, typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename C1, typename C2, typename C3, typename C4,
+ typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d, c.e);
+}
+
+// 4 - 6
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename C1, typename C2, typename C3,
+ typename C4, typename C5, typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename C1, typename C2, typename C3, typename C4,
+ typename C5, typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple4<P1, P2, P3, P4>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// 5 - 0
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple0& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple0& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e);
+}
+
+// 5 - 1
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, c.a);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple1<C1>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, c.a);
+}
+
+// 5 - 2
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename C1, typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, c.a, c.b);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename C1, typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, c.a, c.b);
+}
+
+// 5 - 3
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename C1, typename C2,
+ typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename C1, typename C2, typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c);
+}
+
+// 5 - 4
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename C1, typename C2,
+ typename C3, typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename C1, typename C2, typename C3,
+ typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c, c.d);
+}
+
+// 5 - 5
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename C1, typename C2,
+ typename C3, typename C4, typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename C1, typename C2, typename C3,
+ typename C4, typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c, c.d, c.e);
+}
+
+// 5 - 6
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename C1, typename C2,
+ typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename C1, typename C2, typename C3,
+ typename C4, typename C5, typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple5<P1, P2, P3, P4, P5>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// 6 - 0
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple0& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple0& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f);
+}
+
+// 6 - 1
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename C1>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple1<C1>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f, c.a);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6, typename C1>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple1<C1>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f, c.a);
+}
+
+// 6 - 2
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename C1,
+ typename C2>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple2<C1, C2>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6, typename C1, typename C2>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple2<C1, C2>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b);
+}
+
+// 6 - 3
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename C1,
+ typename C2, typename C3>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6, typename C1, typename C2,
+ typename C3>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple3<C1, C2, C3>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c);
+}
+
+// 6 - 4
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename C1,
+ typename C2, typename C3, typename C4>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c, c.d);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6, typename C1, typename C2,
+ typename C3, typename C4>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple4<C1, C2, C3, C4>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c, c.d);
+}
+
+// 6 - 5
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename C1,
+ typename C2, typename C3, typename C4, typename C5>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c, c.d, c.e);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6, typename C1, typename C2,
+ typename C3, typename C4, typename C5>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple5<C1, C2, C3, C4, C5>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c, c.d, c.e);
+}
+
+// 6 - 6
+template <typename R, typename T, typename Method, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename C1,
+ typename C2, typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToMethod(T* obj, Method method,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (obj->*method)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+template <typename R, typename Function, typename P1, typename P2, typename P3,
+ typename P4, typename P5, typename P6, typename C1, typename C2,
+ typename C3, typename C4, typename C5, typename C6>
+inline R DispatchToFunction(Function function,
+ const Tuple6<P1, P2, P3, P4, P5, P6>& p,
+ const Tuple6<C1, C2, C3, C4, C5, C6>& c) {
+ return (*function)(p.a, p.b, p.c, p.d, p.e, p.f, c.a, c.b, c.c, c.d, c.e, c.f);
+}
+
+// Interface that is exposed to the consumer, that does the actual calling
+// of the method.
+template <typename R, typename Params>
+class MutantRunner {
+ public:
+ virtual R RunWithParams(const Params& params) = 0;
+ virtual ~MutantRunner() {}
+};
+
+// Mutant holds pre-bound arguments (like Task). Like Callback
+// allows call-time arguments. You bind a pointer to the object
+// at creation time.
+template <typename R, typename T, typename Method,
+ typename PreBound, typename Params>
+class Mutant : public MutantRunner<R, Params> {
+ public:
+ Mutant(T* obj, Method method, const PreBound& pb)
+ : obj_(obj), method_(method), pb_(pb) {
+ }
+
+ // MutantRunner implementation
+ virtual R RunWithParams(const Params& params) {
+ return DispatchToMethod<R>(this->obj_, this->method_, pb_, params);
+ }
+
+ T* obj_;
+ Method method_;
+ PreBound pb_;
+};
+
+template <typename R, typename Function, typename PreBound, typename Params>
+class MutantFunction : public MutantRunner<R, Params> {
+ public:
+ MutantFunction(Function function, const PreBound& pb)
+ : function_(function), pb_(pb) {
+ }
+
+ // MutantRunner implementation
+ virtual R RunWithParams(const Params& params) {
+ return DispatchToFunction<R>(function_, pb_, params);
+ }
+
+ Function function_;
+ PreBound pb_;
+};
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+// MutantLateBind is like Mutant, but you bind a pointer to a pointer
+// to the object. This way you can create actions for an object
+// that is not yet created (has only storage for a pointer to it).
+template <typename R, typename T, typename Method,
+ typename PreBound, typename Params>
+class MutantLateObjectBind : public MutantRunner<R, Params> {
+ public:
+ MutantLateObjectBind(T** obj, Method method, const PreBound& pb)
+ : obj_(obj), method_(method), pb_(pb) {
+ }
+
+ // MutantRunner implementation.
+ virtual R RunWithParams(const Params& params) {
+ EXPECT_THAT(*this->obj_, testing::NotNull());
+ if (NULL == *this->obj_)
+ return R();
+ return DispatchToMethod<R>( *this->obj_, this->method_, pb_, params);
+ }
+
+ T** obj_;
+ Method method_;
+ PreBound pb_;
+};
+#endif
+
+// Simple MutantRunner<> wrapper acting as a functor.
+// Redirects operator() to MutantRunner<Params>::Run()
+template <typename R, typename Params>
+struct MutantFunctor {
+ explicit MutantFunctor(MutantRunner<R, Params>* cb) : impl_(cb) {
+ }
+
+ ~MutantFunctor() {
+ }
+
+ inline R operator()() {
+ return impl_->RunWithParams(Tuple0());
+ }
+
+ template <typename Arg1>
+ inline R operator()(const Arg1& a) {
+ return impl_->RunWithParams(Params(a));
+ }
+
+ template <typename Arg1, typename Arg2>
+ inline R operator()(const Arg1& a, const Arg2& b) {
+ return impl_->RunWithParams(Params(a, b));
+ }
+
+ template <typename Arg1, typename Arg2, typename Arg3>
+ inline R operator()(const Arg1& a, const Arg2& b, const Arg3& c) {
+ return impl_->RunWithParams(Params(a, b, c));
+ }
+
+ template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+ inline R operator()(const Arg1& a, const Arg2& b, const Arg3& c,
+ const Arg4& d) {
+ return impl_->RunWithParams(Params(a, b, c, d));
+ }
+
+ private:
+ // We need copy constructor since MutantFunctor is copied few times
+ // inside GMock machinery, hence no DISALLOW_EVIL_CONTRUCTORS
+ MutantFunctor();
+ linked_ptr<MutantRunner<R, Params> > impl_;
+};
+
+// 0 - 0
+template <typename R, typename T, typename U>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)()) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(),
+ Tuple0, Tuple0>
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)()) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(),
+ Tuple0, Tuple0>
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)()) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(),
+ Tuple0, Tuple0>
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)()) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(),
+ Tuple0, Tuple0>
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)()) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(),
+ Tuple0, Tuple0>
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)()) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(),
+ Tuple0, Tuple0>
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 0 - 1
+template <typename R, typename T, typename U, typename A1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(A1)) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(A1),
+ Tuple0, Tuple1<A1> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename A1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(A1)) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(A1),
+ Tuple0, Tuple1<A1> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(A1)) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(A1),
+ Tuple0, Tuple1<A1> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename A1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(A1)) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(A1),
+ Tuple0, Tuple1<A1> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename A1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(A1)) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(A1),
+ Tuple0, Tuple1<A1> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(A1)) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(A1),
+ Tuple0, Tuple1<A1> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 0 - 2
+template <typename R, typename T, typename U, typename A1, typename A2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(A1, A2)) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(A1, A2),
+ Tuple0, Tuple2<A1, A2> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename A1, typename A2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(A1, A2)) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(A1, A2),
+ Tuple0, Tuple2<A1, A2> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(A1, A2)) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(A1, A2),
+ Tuple0, Tuple2<A1, A2> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename A1, typename A2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(A1, A2)) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(A1, A2),
+ Tuple0, Tuple2<A1, A2> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename A1, typename A2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(A1, A2)) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(A1, A2),
+ Tuple0, Tuple2<A1, A2> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(A1, A2)) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(A1, A2),
+ Tuple0, Tuple2<A1, A2> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 0 - 3
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(A1, A2, A3)) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(A1, A2, A3),
+ Tuple0, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(A1, A2, A3)) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(A1, A2, A3),
+ Tuple0, Tuple3<A1, A2, A3> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(A1, A2, A3)) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(A1, A2, A3),
+ Tuple0, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(A1, A2, A3)) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(A1, A2, A3),
+ Tuple0, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(A1, A2, A3)) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(A1, A2, A3),
+ Tuple0, Tuple3<A1, A2, A3> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(A1, A2, A3)) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(A1, A2, A3),
+ Tuple0, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 0 - 4
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(A1, A2, A3, A4)) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(A1, A2, A3, A4),
+ Tuple0, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(A1, A2, A3, A4)) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(A1, A2, A3, A4),
+ Tuple0, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(A1, A2, A3, A4)) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(A1, A2, A3, A4),
+ Tuple0, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(A1, A2, A3, A4)) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(A1, A2, A3, A4),
+ Tuple0, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(A1, A2, A3, A4)) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(A1, A2, A3, A4),
+ Tuple0, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(A1, A2, A3, A4)) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(A1, A2, A3, A4),
+ Tuple0, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 0 - 5
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(A1, A2, A3, A4, A5)) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(A1, A2, A3, A4, A5),
+ Tuple0, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(A1, A2, A3, A4, A5)) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(A1, A2, A3, A4, A5),
+ Tuple0, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(A1, A2, A3, A4, A5)) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(A1, A2, A3, A4, A5),
+ Tuple0, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(A1, A2, A3, A4, A5)) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(A1, A2, A3, A4, A5),
+ Tuple0, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(A1, A2, A3, A4, A5)) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(A1, A2, A3, A4, A5),
+ Tuple0, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(A1, A2, A3, A4, A5)) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(A1, A2, A3, A4, A5),
+ Tuple0, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 0 - 6
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(A1, A2, A3, A4, A5, A6)) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(A1, A2, A3, A4, A5, A6),
+ Tuple0, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(A1, A2, A3, A4, A5, A6)) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(A1, A2, A3, A4, A5, A6),
+ Tuple0, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(A1, A2, A3, A4, A5, A6)) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(A1, A2, A3, A4, A5, A6),
+ Tuple0, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(A1, A2, A3, A4, A5, A6)) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(A1, A2, A3, A4, A5, A6),
+ Tuple0, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(A1, A2, A3, A4, A5, A6)) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(A1, A2, A3, A4, A5, A6),
+ Tuple0, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple());
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(A1, A2, A3, A4, A5, A6)) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(A1, A2, A3, A4, A5, A6),
+ Tuple0, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple());
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 0
+template <typename R, typename T, typename U, typename P1, typename X1>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)(X1), const P1& p1) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(X1),
+ Tuple1<P1>, Tuple0>
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename X1>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)(X1), const P1& p1) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(X1),
+ Tuple1<P1>, Tuple0>
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename X1>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)(X1), const P1& p1) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1),
+ Tuple1<P1>, Tuple0>
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename X1>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1), const P1& p1) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1),
+ Tuple1<P1>, Tuple0>
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename X1>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)(X1), const P1& p1) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(X1),
+ Tuple1<P1>, Tuple0>
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename X1>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1), const P1& p1) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1),
+ Tuple1<P1>, Tuple0>
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 1
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename X1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(X1, A1), const P1& p1) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(X1, A1),
+ Tuple1<P1>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename X1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(X1, A1), const P1& p1) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(X1, A1),
+ Tuple1<P1>, Tuple1<A1> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename X1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(X1, A1), const P1& p1) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, A1),
+ Tuple1<P1>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename X1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, A1), const P1& p1) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, A1),
+ Tuple1<P1>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename X1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(X1, A1), const P1& p1) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, A1),
+ Tuple1<P1>, Tuple1<A1> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename X1>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, A1), const P1& p1) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, A1),
+ Tuple1<P1>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 2
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename X1>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(X1, A1, A2), const P1& p1) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(X1, A1, A2),
+ Tuple1<P1>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename X1>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(X1, A1, A2), const P1& p1) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(X1, A1, A2),
+ Tuple1<P1>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename X1>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(X1, A1, A2), const P1& p1) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, A1, A2),
+ Tuple1<P1>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename X1>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, A1, A2), const P1& p1) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, A1, A2),
+ Tuple1<P1>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename X1>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(X1, A1, A2), const P1& p1) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, A1, A2),
+ Tuple1<P1>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename X1>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, A1, A2), const P1& p1) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, A1, A2),
+ Tuple1<P1>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 3
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename X1>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(X1, A1, A2, A3), const P1& p1) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(X1, A1, A2, A3),
+ Tuple1<P1>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename X1>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(X1, A1, A2, A3), const P1& p1) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(X1, A1, A2, A3),
+ Tuple1<P1>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename X1>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(X1, A1, A2, A3), const P1& p1) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, A1, A2, A3),
+ Tuple1<P1>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename X1>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, A1, A2, A3), const P1& p1) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, A1, A2, A3),
+ Tuple1<P1>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename X1>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(X1, A1, A2, A3), const P1& p1) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, A1, A2, A3),
+ Tuple1<P1>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename X1>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, A1, A2, A3), const P1& p1) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, A1, A2, A3),
+ Tuple1<P1>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 4
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename X1>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(X1, A1, A2, A3, A4), const P1& p1) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(X1, A1, A2, A3, A4),
+ Tuple1<P1>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename A4, typename X1>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(X1, A1, A2, A3, A4), const P1& p1) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(X1, A1, A2, A3, A4),
+ Tuple1<P1>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename X1>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(X1, A1, A2, A3, A4), const P1& p1) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, A1, A2, A3, A4),
+ Tuple1<P1>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename X1>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, A1, A2, A3, A4),
+ const P1& p1) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, A1, A2, A3, A4),
+ Tuple1<P1>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename A4, typename X1>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(X1, A1, A2, A3, A4), const P1& p1) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, A1, A2, A3, A4),
+ Tuple1<P1>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename X1>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, A1, A2, A3, A4),
+ const P1& p1) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, A1, A2, A3, A4),
+ Tuple1<P1>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 5
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(X1, A1, A2, A3, A4, A5), const P1& p1) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(X1, A1, A2, A3, A4, A5),
+ Tuple1<P1>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(X1, A1, A2, A3, A4, A5), const P1& p1) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(X1, A1, A2, A3, A4, A5),
+ Tuple1<P1>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(X1, A1, A2, A3, A4, A5), const P1& p1) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, A1, A2, A3, A4, A5),
+ Tuple1<P1>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, A1, A2, A3, A4, A5),
+ const P1& p1) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, A1, A2, A3, A4, A5),
+ Tuple1<P1>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(X1, A1, A2, A3, A4, A5), const P1& p1) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, A1, A2, A3, A4, A5),
+ Tuple1<P1>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, A1, A2, A3, A4, A5),
+ const P1& p1) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, A1, A2, A3, A4, A5),
+ Tuple1<P1>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 1 - 6
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(X1, A1, A2, A3, A4, A5, A6),
+ const P1& p1) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(X1, A1, A2, A3, A4, A5, A6),
+ Tuple1<P1>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(X1, A1, A2, A3, A4, A5, A6), const P1& p1) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(X1, A1, A2, A3, A4, A5, A6),
+ Tuple1<P1>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(X1, A1, A2, A3, A4, A5, A6),
+ const P1& p1) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, A1, A2, A3, A4, A5, A6),
+ Tuple1<P1>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, A1, A2, A3, A4, A5, A6),
+ const P1& p1) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, A1, A2, A3, A4, A5, A6),
+ Tuple1<P1>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(X1, A1, A2, A3, A4, A5, A6),
+ const P1& p1) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, A1, A2, A3, A4, A5, A6),
+ Tuple1<P1>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, A1, A2, A3, A4, A5, A6),
+ const P1& p1) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, A1, A2, A3, A4, A5, A6),
+ Tuple1<P1>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 0
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)(X1, X2), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(X1, X2),
+ Tuple2<P1, P2>, Tuple0>
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename X1, typename X2>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)(X1, X2), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(X1, X2),
+ Tuple2<P1, P2>, Tuple0>
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)(X1, X2), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2),
+ Tuple2<P1, P2>, Tuple0>
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2),
+ Tuple2<P1, P2>, Tuple0>
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename X1, typename X2>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)(X1, X2), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2),
+ Tuple2<P1, P2>, Tuple0>
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2),
+ Tuple2<P1, P2>, Tuple0>
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 1
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename X1, typename X2>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, A1), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, A1),
+ Tuple2<P1, P2>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(X1, X2, A1), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(X1, X2, A1),
+ Tuple2<P1, P2>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename X1, typename X2>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, A1), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, A1),
+ Tuple2<P1, P2>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename X1, typename X2>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, A1), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, A1),
+ Tuple2<P1, P2>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(X1, X2, A1), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, A1),
+ Tuple2<P1, P2>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename X1, typename X2>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, A1), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, A1),
+ Tuple2<P1, P2>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 2
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename X1, typename X2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, A1, A2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, A1, A2),
+ Tuple2<P1, P2>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(X1, X2, A1, A2), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(X1, X2, A1, A2),
+ Tuple2<P1, P2>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename X1, typename X2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, A1, A2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, A1, A2),
+ Tuple2<P1, P2>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename X1, typename X2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, A1, A2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, A1, A2),
+ Tuple2<P1, P2>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(X1, X2, A1, A2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, A1, A2),
+ Tuple2<P1, P2>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename X1, typename X2>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, A1, A2), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, A1, A2),
+ Tuple2<P1, P2>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 3
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename X1, typename X2>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, A1, A2, A3), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, A1, A2, A3),
+ Tuple2<P1, P2>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename X1, typename X2>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(X1, X2, A1, A2, A3), const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(X1, X2, A1, A2, A3),
+ Tuple2<P1, P2>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename X1, typename X2>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, A1, A2, A3), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, A1, A2, A3),
+ Tuple2<P1, P2>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename X1, typename X2>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3),
+ Tuple2<P1, P2>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename X1, typename X2>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(X1, X2, A1, A2, A3), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, A1, A2, A3),
+ Tuple2<P1, P2>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename X1, typename X2>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3),
+ Tuple2<P1, P2>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 4
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, A1, A2, A3, A4), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, A1, A2, A3, A4),
+ Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename A4, typename X1, typename X2>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(X1, X2, A1, A2, A3, A4), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(X1, X2, A1, A2, A3, A4),
+ Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, A1, A2, A3, A4), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, A1, A2, A3, A4),
+ Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3, A4),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3, A4),
+ Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename A4, typename X1, typename X2>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(X1, X2, A1, A2, A3, A4), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, A1, A2, A3, A4),
+ Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3, A4),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3, A4),
+ Tuple2<P1, P2>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 5
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, A1, A2, A3, A4, A5), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, A1, A2, A3, A4, A5),
+ Tuple2<P1, P2>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename X1, typename X2>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(X1, X2, A1, A2, A3, A4, A5), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(X1, X2, A1, A2, A3, A4, A5),
+ Tuple2<P1, P2>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, A1, A2, A3, A4, A5), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, A1, A2, A3, A4, A5),
+ Tuple2<P1, P2>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3, A4, A5),
+ Tuple2<P1, P2>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename X1, typename X2>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(X1, X2, A1, A2, A3, A4, A5), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, A1, A2, A3, A4, A5),
+ Tuple2<P1, P2>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename X1, typename X2>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3, A4, A5),
+ Tuple2<P1, P2>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 2 - 6
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename X1, typename X2>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, A1, A2, A3, A4, A5, A6),
+ Tuple2<P1, P2>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(X1, X2, A1, A2, A3, A4, A5, A6), const P1& p1,
+ const P2& p2) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(X1, X2, A1, A2, A3, A4, A5, A6),
+ Tuple2<P1, P2>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename X1, typename X2>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, A1, A2, A3, A4, A5, A6),
+ Tuple2<P1, P2>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename X1, typename X2>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3, A4, A5, A6),
+ Tuple2<P1, P2>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6, typename X1,
+ typename X2>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(X1, X2, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, A1, A2, A3, A4, A5, A6),
+ Tuple2<P1, P2>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename X1, typename X2>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, A1, A2, A3, A4, A5, A6),
+ Tuple2<P1, P2>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 0
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3),
+ Tuple3<P1, P2, P3>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)(X1, X2, X3), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(X1, X2, X3),
+ Tuple3<P1, P2, P3>, Tuple0>
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3),
+ Tuple3<P1, P2, P3>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3),
+ Tuple3<P1, P2, P3>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)(X1, X2, X3), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3),
+ Tuple3<P1, P2, P3>, Tuple0>
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3),
+ Tuple3<P1, P2, P3>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 1
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, A1), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, A1),
+ Tuple3<P1, P2, P3>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(X1, X2, X3, A1), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, A1),
+ Tuple3<P1, P2, P3>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, A1), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, A1),
+ Tuple3<P1, P2, P3>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, A1), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, A1),
+ Tuple3<P1, P2, P3>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, A1), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, A1),
+ Tuple3<P1, P2, P3>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, A1), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, A1),
+ Tuple3<P1, P2, P3>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 2
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename X1, typename X2,
+ typename X3>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, A1, A2),
+ Tuple3<P1, P2, P3>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(X1, X2, X3, A1, A2), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, A1, A2),
+ Tuple3<P1, P2, P3>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename X1, typename X2,
+ typename X3>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, A1, A2),
+ Tuple3<P1, P2, P3>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename X1, typename X2,
+ typename X3>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2),
+ Tuple3<P1, P2, P3>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, A1, A2),
+ Tuple3<P1, P2, P3>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename X1, typename X2,
+ typename X3>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2),
+ Tuple3<P1, P2, P3>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 3
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, A1, A2, A3),
+ Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(X1, X2, X3, A1, A2, A3), const P1& p1, const P2& p2,
+ const P3& p3) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, A1, A2, A3),
+ Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, A1, A2, A3),
+ Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3),
+ Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, A1, A2, A3),
+ Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3),
+ Tuple3<P1, P2, P3>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 4
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, A1, A2, A3, A4), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, A1, A2, A3, A4),
+ Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename A4, typename X1, typename X2,
+ typename X3>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(X1, X2, X3, A1, A2, A3, A4), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, A1, A2, A3, A4),
+ Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, A1, A2, A3, A4), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, A1, A2, A3, A4),
+ Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3, A4),
+ Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename A4, typename X1, typename X2,
+ typename X3>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, A1, A2, A3, A4), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, A1, A2, A3, A4),
+ Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3, A4),
+ Tuple3<P1, P2, P3>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 5
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, A1, A2, A3, A4, A5),
+ Tuple3<P1, P2, P3>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(X1, X2, X3, A1, A2, A3, A4, A5), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, A1, A2, A3, A4, A5),
+ Tuple3<P1, P2, P3>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, A1, A2, A3, A4, A5),
+ Tuple3<P1, P2, P3>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3, A4, A5),
+ Tuple3<P1, P2, P3>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1,
+ typename X2, typename X3>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, A1, A2, A3, A4, A5),
+ Tuple3<P1, P2, P3>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3, A4, A5),
+ Tuple3<P1, P2, P3>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 3 - 6
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ Tuple3<P1, P2, P3>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(X1, X2, X3, A1, A2, A3, A4, A5, A6), const P1& p1,
+ const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ Tuple3<P1, P2, P3>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ Tuple3<P1, P2, P3>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ Tuple3<P1, P2, P3>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ Tuple3<P1, P2, P3>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename X1, typename X2, typename X3>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, A1, A2, A3, A4, A5, A6),
+ Tuple3<P1, P2, P3>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 0
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4),
+ Tuple4<P1, P2, P3, P4>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)(X1, X2, X3, X4), const P1& p1, const P2& p2,
+ const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4),
+ Tuple4<P1, P2, P3, P4>, Tuple0>
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4),
+ Tuple4<P1, P2, P3, P4>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4),
+ Tuple4<P1, P2, P3, P4>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4),
+ Tuple4<P1, P2, P3, P4>, Tuple0>
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4),
+ Tuple4<P1, P2, P3, P4>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 1
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, A1),
+ Tuple4<P1, P2, P3, P4>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, A1), const P1& p1, const P2& p2,
+ const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, A1),
+ Tuple4<P1, P2, P3, P4>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, A1),
+ Tuple4<P1, P2, P3, P4>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1),
+ Tuple4<P1, P2, P3, P4>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, A1),
+ Tuple4<P1, P2, P3, P4>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1),
+ Tuple4<P1, P2, P3, P4>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 2
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename X1,
+ typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, A1, A2),
+ Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, A1, A2), const P1& p1, const P2& p2,
+ const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, A1, A2),
+ Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename X1,
+ typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, A1, A2),
+ Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename X1,
+ typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2),
+ Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, A1, A2),
+ Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename X1,
+ typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2),
+ Tuple4<P1, P2, P3, P4>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 3
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3),
+ Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, A1, A2, A3),
+ Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3),
+ Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3),
+ Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, A1, A2, A3),
+ Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3),
+ Tuple4<P1, P2, P3, P4>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 4
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3, A4),
+ Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename A4, typename X1,
+ typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, A1, A2, A3, A4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, A1, A2, A3, A4),
+ Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3, A4),
+ Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3, A4),
+ Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename A4, typename X1,
+ typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, A1, A2, A3, A4),
+ Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3, A4),
+ Tuple4<P1, P2, P3, P4>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 5
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ Tuple4<P1, P2, P3, P4>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, A1, A2, A3, A4, A5), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ Tuple4<P1, P2, P3, P4>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ Tuple4<P1, P2, P3, P4>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3, A4,
+ A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ Tuple4<P1, P2, P3, P4>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ Tuple4<P1, P2, P3, P4>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1, typename X2, typename X3,
+ typename X4>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3, A4,
+ A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5),
+ Tuple4<P1, P2, P3, P4>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 4 - 6
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ Tuple4<P1, P2, P3, P4>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ Tuple4<P1, P2, P3, P4>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ Tuple4<P1, P2, P3, P4>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3, A4,
+ A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ Tuple4<P1, P2, P3, P4>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename A1, typename A2, typename A3, typename A4, typename A5,
+ typename A6, typename X1, typename X2, typename X3, typename X4>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ Tuple4<P1, P2, P3, P4>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1, typename X2,
+ typename X3, typename X4>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, A1, A2, A3, A4,
+ A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, A1, A2, A3, A4, A5, A6),
+ Tuple4<P1, P2, P3, P4>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 0
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5), const P1& p1, const P2& p2,
+ const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple0>
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple0>
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 1
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, A1),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, A1), const P1& p1, const P2& p2,
+ const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, A1),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, A1),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, A1),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 2
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename X1, typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, A1, A2),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename X1, typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename X1, typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, A1, A2),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename X1, typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 3
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, A1, A2, A3),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, A1, A2, A3),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 4
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename A4,
+ typename X1, typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, A1, A2, A3, A4), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3,
+ A4), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename A4,
+ typename X1, typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3,
+ A4), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 5
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3,
+ A4, A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename X1, typename X2, typename X3, typename X4,
+ typename X5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3,
+ A4, A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 5 - 6
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3,
+ A4, A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6, typename X1, typename X2, typename X3,
+ typename X4, typename X5>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6, typename X1,
+ typename X2, typename X3, typename X4, typename X5>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, A1, A2, A3,
+ A4, A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, A1, A2, A3, A4, A5, A6),
+ Tuple5<P1, P2, P3, P4, P5>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 0
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6), const P1& p1, const P2& p2,
+ const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple0>
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple0>* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple0>(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple0>
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple0>
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple0>* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple0>
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple0>(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 1
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6, A1),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6, A1), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6, A1),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple1<A1> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple1<A1> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple1<A1> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple1<A1> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple1<A1> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 2
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename X1, typename X2, typename X3, typename X4,
+ typename X5, typename X6>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6, A1, A2), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6, A1, A2),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename X1, typename X2, typename X3, typename X4,
+ typename X5, typename X6>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename X1, typename X2, typename X3, typename X4,
+ typename X5, typename X6>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6, A1, A2),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple2<A1, A2> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename X1, typename X2, typename X3, typename X4,
+ typename X5, typename X6>
+inline MutantFunctor<R, Tuple2<A1, A2> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple2<A1, A2> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple2<A1, A2> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple2<A1, A2> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 3
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6, A1, A2, A3), const P1& p1,
+ const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple3<A1, A2, A3> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple3<A1, A2, A3> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple3<A1, A2, A3> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple3<A1, A2, A3> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple3<A1, A2, A3> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 4
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename A4, typename X1, typename X2, typename X3, typename X4,
+ typename X5, typename X6>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3, A4), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename A4, typename X1, typename X2, typename X3, typename X4,
+ typename X5, typename X6>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple4<A1, A2, A3, A4> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple4<A1, A2, A3, A4> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3, A4), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple4<A1, A2, A3, A4> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple4<A1, A2, A3, A4> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple4<A1, A2, A3, A4> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 5
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4,
+ A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4,
+ A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3, A4, A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename X1, typename X2, typename X3,
+ typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4,
+ A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple5<A1, A2, A3, A4, A5> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename X1,
+ typename X2, typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3, A4, A5), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple5<A1, A2, A3, A4, A5> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple5<A1, A2, A3, A4, A5> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple5<A1, A2, A3, A4, A5> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+// 6 - 6
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (*function)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (U::*method)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5,
+ A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5,
+ const P6& p6) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+
+#if defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T* obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3, A4, A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new Mutant<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(R (__stdcall *function)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4,
+ A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantFunction<R, R (__stdcall *)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (function, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#ifdef GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+template <typename R, typename T, typename U, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6, typename A1,
+ typename A2, typename A3, typename A4, typename A5, typename A6,
+ typename X1, typename X2, typename X3, typename X4, typename X5,
+ typename X6>
+inline MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >
+CreateFunctor(T** obj, R (__stdcall U::*method)(X1, X2, X3, X4, X5, X6, A1, A2,
+ A3, A4, A5, A6), const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ MutantRunner<R, Tuple6<A1, A2, A3, A4, A5, A6> >* t =
+ new MutantLateObjectBind<R, T, R (__stdcall U::*)(X1, X2, X3, X4, X5, X6, A1, A2, A3, A4, A5, A6),
+ Tuple6<P1, P2, P3, P4, P5, P6>, Tuple6<A1, A2, A3, A4, A5, A6> >
+ (obj, method, MakeTuple(p1, p2, p3, p4, p5, p6));
+ return MutantFunctor<R, Tuple6<A1, A2, A3, A4, A5, A6> >(t);
+}
+#endif // GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
+#endif // defined (OS_WIN) && !defined (ARCH_CPU_X86_64)
+
+} // namespace testing
+
+#endif // TESTING_GMOCK_MUTANT_H_
diff --git a/testing/gtest.gyp b/testing/gtest.gyp
new file mode 100644
index 0000000..671a508
--- /dev/null
+++ b/testing/gtest.gyp
@@ -0,0 +1,219 @@
+# Copyright (c) 2012 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.
+
+{
+ 'includes': [
+ 'gtest.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'gtest',
+ 'toolsets': ['host', 'target'],
+ 'type': 'static_library',
+ 'sources': [
+ '<@(gtest_sources)',
+ ],
+ 'include_dirs': [
+ 'gtest',
+ 'gtest/include',
+ ],
+ 'dependencies': [
+ 'gtest_prod',
+ ],
+ 'defines': [
+ # In order to allow regex matches in gtest to be shared between Windows
+ # and other systems, we tell gtest to always use it's internal engine.
+ 'GTEST_HAS_POSIX_RE=0',
+ # Chrome doesn't support / require C++11, yet.
+ 'GTEST_LANG_CXX11=0',
+ ],
+ 'all_dependent_settings': {
+ 'defines': [
+ 'GTEST_HAS_POSIX_RE=0',
+ 'GTEST_LANG_CXX11=0',
+ ],
+ },
+ 'conditions': [
+ ['OS == "mac" or OS == "ios"', {
+ 'sources': [
+ 'gtest_mac.h',
+ 'gtest_mac.mm',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+ ],
+ },
+ }],
+ ['OS == "mac"', {
+ 'sources': [
+ 'platform_test_mac.mm',
+ ],
+ }],
+ ['OS == "ios"', {
+ 'dependencies' : [
+ '<(DEPTH)/testing/iossim/iossim.gyp:iossim#host',
+ ],
+ 'direct_dependent_settings': {
+ 'target_conditions': [
+ # Turn all tests into bundles on iOS because that's the only
+ # type of executable supported for iOS.
+ ['_type=="executable"', {
+ 'variables': {
+ # Use a variable so the path gets fixed up so it is always
+ # correct when INFOPLIST_FILE finally gets set.
+ 'ios_unittest_info_plist_path':
+ '<(DEPTH)/testing/gtest_ios/unittest-Info.plist',
+ },
+ 'mac_bundle': 1,
+ 'xcode_settings': {
+ 'BUNDLE_ID_TEST_NAME':
+ '>!(echo ">(_target_name)" | sed -e "s/_//g")',
+ 'INFOPLIST_FILE': '>(ios_unittest_info_plist_path)',
+ },
+ 'mac_bundle_resources': [
+ '<(ios_unittest_info_plist_path)',
+ '<(DEPTH)/testing/gtest_ios/Default-568h@2x.png',
+ ],
+ 'mac_bundle_resources!': [
+ '<(ios_unittest_info_plist_path)',
+ ],
+ }],
+ ],
+ },
+ 'sources': [
+ 'coverage_util_ios.cc',
+ 'coverage_util_ios.h',
+ 'platform_test_ios.mm',
+ ],
+ }],
+ ['OS=="ios" and asan==1', {
+ 'direct_dependent_settings': {
+ 'target_conditions': [
+ # Package the ASan runtime dylib into the test app bundles.
+ ['_type=="executable"', {
+ 'postbuilds': [
+ {
+ 'variables': {
+ # Define copy_asan_dylib_path in a variable ending in
+ # _path so that gyp understands it's a path and
+ # performs proper relativization during dict merging.
+ 'copy_asan_dylib_path':
+ '<(DEPTH)/build/mac/copy_asan_runtime_dylib.sh',
+ },
+ 'postbuild_name': 'Copy ASan runtime dylib',
+ 'action': [
+ '>(copy_asan_dylib_path)',
+ ],
+ },
+ ],
+ }],
+ ],
+ },
+ }],
+ ['os_posix == 1', {
+ 'defines': [
+ # gtest isn't able to figure out when RTTI is disabled for gcc
+ # versions older than 4.3.2, and assumes it's enabled. Our Mac
+ # and Linux builds disable RTTI, and cannot guarantee that the
+ # compiler will be 4.3.2. or newer. The Mac, for example, uses
+ # 4.2.1 as that is the latest available on that platform. gtest
+ # must be instructed that RTTI is disabled here, and for any
+ # direct dependents that might include gtest headers.
+ 'GTEST_HAS_RTTI=0',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'GTEST_HAS_RTTI=0',
+ ],
+ },
+ }],
+ ['OS=="android" and android_app_abi=="x86"', {
+ 'defines': [
+ 'GTEST_HAS_CLONE=0',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'GTEST_HAS_CLONE=0',
+ ],
+ },
+ }],
+ ['OS=="android"', {
+ # We want gtest features that use tr1::tuple, but we currently
+ # don't support the variadic templates used by libstdc++'s
+ # implementation. gtest supports this scenario by providing its
+ # own implementation but we must opt in to it.
+ 'defines': [
+ 'GTEST_USE_OWN_TR1_TUPLE=1',
+ # GTEST_USE_OWN_TR1_TUPLE only works if GTEST_HAS_TR1_TUPLE is set.
+ # gtest r625 made it so that GTEST_HAS_TR1_TUPLE is set to 0
+ # automatically on android, so it has to be set explicitly here.
+ 'GTEST_HAS_TR1_TUPLE=1',
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'GTEST_USE_OWN_TR1_TUPLE=1',
+ 'GTEST_HAS_TR1_TUPLE=1',
+ ],
+ },
+ }],
+ ],
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'UNIT_TEST',
+ ],
+ 'include_dirs': [
+ 'gtest/include', # So that gtest headers can find themselves.
+ ],
+ 'target_conditions': [
+ ['_type=="executable"', {
+ 'test': 1,
+ 'conditions': [
+ ['OS=="mac"', {
+ 'run_as': {
+ 'action????': ['${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}'],
+ },
+ }],
+ ['OS=="ios"', {
+ 'variables': {
+ # Use a variable so the path gets fixed up so it is always
+ # correct when the action finally gets used.
+ 'ios_run_unittest_script_path':
+ '<(DEPTH)/testing/gtest_ios/run-unittest.sh',
+ },
+ 'run_as': {
+ 'action????': ['>(ios_run_unittest_script_path)'],
+ },
+ }],
+ ['OS=="win"', {
+ 'run_as': {
+ 'action????': ['$(TargetPath)', '--gtest_print_time'],
+ },
+ }],
+ ],
+ }],
+ ],
+ 'msvs_disabled_warnings': [4800],
+ },
+ },
+ {
+ 'target_name': 'gtest_main',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'gtest',
+ ],
+ 'sources': [
+ 'gtest/src/gtest_main.cc',
+ ],
+ },
+ {
+ 'target_name': 'gtest_prod',
+ 'toolsets': ['host', 'target'],
+ 'type': 'none',
+ 'sources': [
+ 'gtest/include/gtest/gtest_prod.h',
+ ],
+ },
+ ],
+}
diff --git a/testing/gtest.gypi b/testing/gtest.gypi
new file mode 100644
index 0000000..ca12e1b
--- /dev/null
+++ b/testing/gtest.gypi
@@ -0,0 +1,41 @@
+# Copyright 2014 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.
+
+{
+ 'variables': {
+ 'gtest_sources': [
+ 'gtest/include/gtest/gtest-death-test.h',
+ 'gtest/include/gtest/gtest-message.h',
+ 'gtest/include/gtest/gtest-param-test.h',
+ 'gtest/include/gtest/gtest-printers.h',
+ 'gtest/include/gtest/gtest-spi.h',
+ 'gtest/include/gtest/gtest-test-part.h',
+ 'gtest/include/gtest/gtest-typed-test.h',
+ 'gtest/include/gtest/gtest.h',
+ 'gtest/include/gtest/gtest_pred_impl.h',
+ 'gtest/include/gtest/gtest_prod.h',
+ 'gtest/include/gtest/internal/gtest-death-test-internal.h',
+ 'gtest/include/gtest/internal/gtest-filepath.h',
+ 'gtest/include/gtest/internal/gtest-internal.h',
+ 'gtest/include/gtest/internal/gtest-linked_ptr.h',
+ 'gtest/include/gtest/internal/gtest-param-util-generated.h',
+ 'gtest/include/gtest/internal/gtest-param-util.h',
+ 'gtest/include/gtest/internal/gtest-port.h',
+ 'gtest/include/gtest/internal/gtest-string.h',
+ 'gtest/include/gtest/internal/gtest-tuple.h',
+ 'gtest/include/gtest/internal/gtest-type-util.h',
+ 'gtest/src/gtest-death-test.cc',
+ 'gtest/src/gtest-filepath.cc',
+ 'gtest/src/gtest-internal-inl.h',
+ 'gtest/src/gtest-port.cc',
+ 'gtest/src/gtest-printers.cc',
+ 'gtest/src/gtest-test-part.cc',
+ 'gtest/src/gtest-typed-test.cc',
+ 'gtest/src/gtest.cc',
+ 'multiprocess_func_list.cc',
+ 'multiprocess_func_list.h',
+ 'platform_test.h',
+ ],
+ },
+}
diff --git a/testing/gtest_ios/Default-568h@2x.png b/testing/gtest_ios/Default-568h@2x.png
new file mode 100644
index 0000000..8c9089d
--- /dev/null
+++ b/testing/gtest_ios/Default-568h@2x.png
Binary files differ
diff --git a/testing/gtest_ios/run-unittest.sh b/testing/gtest_ios/run-unittest.sh
new file mode 100755
index 0000000..1598630
--- /dev/null
+++ b/testing/gtest_ios/run-unittest.sh
@@ -0,0 +1,87 @@
+#!/bin/bash -p
+
+# Copyright (c) 2012 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.
+
+set -eu
+
+# Environment sanitization. Set a known-safe PATH. Clear environment variables
+# that might impact the interpreter's operation. The |bash -p| invocation
+# on the #! line takes the bite out of BASH_ENV, ENV, and SHELLOPTS (among
+# other features), but clearing them here ensures that they won't impact any
+# shell scripts used as utility programs. SHELLOPTS is read-only and can't be
+# unset, only unexported.
+export PATH="/usr/bin:/bin:/usr/sbin:/sbin"
+unset BASH_ENV CDPATH ENV GLOBIGNORE IFS POSIXLY_CORRECT
+export -n SHELLOPTS
+
+readonly ScriptDir=$(dirname "$(echo ${0} | sed -e "s,^\([^/]\),$(pwd)/\1,")")
+readonly ScriptName=$(basename "${0}")
+readonly ThisScript="${ScriptDir}/${ScriptName}"
+readonly SimExecutable="${BUILD_DIR}/ninja-iossim/${CONFIGURATION}/iossim"
+
+# Helper to print a line formatted for Xcodes build output parser.
+XcodeNote() {
+ echo "${ThisScript}:${1}: note: ${2}"
+}
+
+# Helper to print a divider to make things stick out in a busy output window.
+XcodeHeader() {
+ echo "note: _________________________________________________________________"
+ echo "note: _________________________________________________________________"
+ echo "note: _________________________________________________________________"
+ XcodeNote "$1" ">>>>> $2"
+ echo "note: _________________________________________________________________"
+ echo "note: _________________________________________________________________"
+ echo "note: _________________________________________________________________"
+}
+
+# Kills the iPhone Simulator if it is running.
+KillSimulator() {
+ /usr/bin/killall "iPhone Simulator" 2> /dev/null || true
+}
+
+# Runs tests via the iPhone Simulator for multiple devices.
+RunTests() {
+ local -r appPath="${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app"
+
+ if [[ ! -x "${SimExecutable}" ]]; then
+ echo "Unable to run tests: ${SimExecutable} was not found/executable."
+ exit 1
+ fi
+
+ for device in 'iPhone' 'iPad'; do
+ iosVersion="6.1"
+ KillSimulator
+ local command=(
+ "${SimExecutable}" "-d${device}" "-s${iosVersion}" "${appPath}"
+ )
+ # Pass along any command line flags
+ if [[ "$#" -gt 0 ]]; then
+ command+=( "--" "${@}" )
+ fi
+ XcodeHeader ${LINENO} "Launching tests for ${device} (iOS ${iosVersion})"
+ "${command[@]}"
+
+ # If the command didn't exit successfully, abort.
+ if [[ $? -ne 0 ]]; then
+ exit $?;
+ fi
+ done
+}
+
+# Time to get to work.
+
+if [[ "${PLATFORM_NAME}" != "iphonesimulator" ]]; then
+ XcodeNote ${LINENO} "Skipping running of unittests for device build."
+else
+ if [[ "$#" -gt 0 ]]; then
+ RunTests "${@}"
+ else
+ RunTests
+ fi
+ KillSimulator
+fi
+
+exit 0
diff --git a/testing/gtest_ios/unittest-Info.plist b/testing/gtest_ios/unittest-Info.plist
new file mode 100644
index 0000000..fc21034
--- /dev/null
+++ b/testing/gtest_ios/unittest-Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.google.gtest.${BUNDLE_ID_TEST_NAME}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UISupportedInterfaceOrientation</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/testing/gtest_mac.h b/testing/gtest_mac.h
new file mode 100644
index 0000000..aa48c94
--- /dev/null
+++ b/testing/gtest_mac.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 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.
+
+#ifndef TESTING_GTEST_MAC_H_
+#define TESTING_GTEST_MAC_H_
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/gtest.h>
+
+#ifdef GTEST_OS_MAC
+
+#import <Foundation/Foundation.h>
+
+namespace testing {
+namespace internal {
+
+// This overloaded version allows comparison between ObjC objects that conform
+// to the NSObject protocol. Used to implement {ASSERT|EXPECT}_EQ().
+GTEST_API_ AssertionResult CmpHelperNSEQ(const char* expected_expression,
+ const char* actual_expression,
+ id<NSObject> expected,
+ id<NSObject> actual);
+
+// This overloaded version allows comparison between ObjC objects that conform
+// to the NSObject protocol. Used to implement {ASSERT|EXPECT}_NE().
+GTEST_API_ AssertionResult CmpHelperNSNE(const char* expected_expression,
+ const char* actual_expression,
+ id<NSObject> expected,
+ id<NSObject> actual);
+
+} // namespace internal
+} // namespace testing
+
+// Tests that [expected isEqual:actual].
+#define EXPECT_NSEQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNSEQ, expected, actual)
+#define EXPECT_NSNE(val1, val2) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNSNE, val1, val2)
+
+#define ASSERT_NSEQ(expected, actual) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNSEQ, expected, actual)
+#define ASSERT_NSNE(val1, val2) \
+ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNSNE, val1, val2)
+
+#endif // GTEST_OS_MAC
+
+#endif // TESTING_GTEST_MAC_H_
diff --git a/testing/gtest_mac.mm b/testing/gtest_mac.mm
new file mode 100644
index 0000000..b39d258
--- /dev/null
+++ b/testing/gtest_mac.mm
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 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 "gtest_mac.h"
+
+#include <string>
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/internal/gtest-string.h>
+#include <gtest/gtest.h>
+
+#ifdef GTEST_OS_MAC
+
+#import <Foundation/Foundation.h>
+
+namespace testing {
+namespace internal {
+
+// Handles nil values for |obj| properly by using safe printing of %@ in
+// -stringWithFormat:.
+static inline const char* StringDescription(id<NSObject> obj) {
+ return [[NSString stringWithFormat:@"%@", obj] UTF8String];
+}
+
+// This overloaded version allows comparison between ObjC objects that conform
+// to the NSObject protocol. Used to implement {ASSERT|EXPECT}_EQ().
+GTEST_API_ AssertionResult CmpHelperNSEQ(const char* expected_expression,
+ const char* actual_expression,
+ id<NSObject> expected,
+ id<NSObject> actual) {
+ if (expected == actual || [expected isEqual:actual]) {
+ return AssertionSuccess();
+ }
+ return EqFailure(expected_expression,
+ actual_expression,
+ std::string(StringDescription(expected)),
+ std::string(StringDescription(actual)),
+ false);
+}
+
+// This overloaded version allows comparison between ObjC objects that conform
+// to the NSObject protocol. Used to implement {ASSERT|EXPECT}_NE().
+GTEST_API_ AssertionResult CmpHelperNSNE(const char* expected_expression,
+ const char* actual_expression,
+ id<NSObject> expected,
+ id<NSObject> actual) {
+ if (expected != actual && ![expected isEqual:actual]) {
+ return AssertionSuccess();
+ }
+ Message msg;
+ msg << "Expected: (" << expected_expression << ") != (" << actual_expression
+ << "), actual: " << StringDescription(expected)
+ << " vs " << StringDescription(actual);
+ return AssertionFailure(msg);
+}
+
+} // namespace internal
+} // namespace testing
+
+#endif // GTEST_OS_MAC
diff --git a/testing/gtest_mac_unittest.mm b/testing/gtest_mac_unittest.mm
new file mode 100644
index 0000000..9363b41
--- /dev/null
+++ b/testing/gtest_mac_unittest.mm
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 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.
+
+// Note that while this file is in testing/ and tests GTest macros, it is built
+// as part of Chromium's unit_tests target because the project does not build
+// or run GTest's internal test suite.
+
+#import "testing/gtest_mac.h"
+
+#import <Foundation/Foundation.h>
+
+#include "base/mac/scoped_nsautorelease_pool.h"
+#include "testing/gtest/include/gtest/internal/gtest-port.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(GTestMac, ExpectNSEQ) {
+ base::mac::ScopedNSAutoreleasePool pool;
+
+ EXPECT_NSEQ(@"a", @"a");
+
+ NSString* s1 = [NSString stringWithUTF8String:"a"];
+ NSString* s2 = @"a";
+ EXPECT_NE(s1, s2);
+ EXPECT_NSEQ(s1, s2);
+}
+
+TEST(GTestMac, AssertNSEQ) {
+ base::mac::ScopedNSAutoreleasePool pool;
+
+ NSString* s1 = [NSString stringWithUTF8String:"a"];
+ NSString* s2 = @"a";
+ EXPECT_NE(s1, s2);
+ ASSERT_NSEQ(s1, s2);
+}
+
+TEST(GTestMac, ExpectNSNE) {
+ base::mac::ScopedNSAutoreleasePool pool;
+
+ EXPECT_NSNE([NSNumber numberWithInt:2], [NSNumber numberWithInt:42]);
+}
+
+TEST(GTestMac, AssertNSNE) {
+ base::mac::ScopedNSAutoreleasePool pool;
+
+ ASSERT_NSNE(@"a", @"b");
+}
+
+TEST(GTestMac, ExpectNSNil) {
+ base::mac::ScopedNSAutoreleasePool pool;
+
+ EXPECT_NSEQ(nil, nil);
+ EXPECT_NSNE(nil, @"a");
+ EXPECT_NSNE(@"a", nil);
+
+ // TODO(shess): Test that EXPECT_NSNE(nil, nil) fails.
+}
diff --git a/testing/gtest_nacl.gyp b/testing/gtest_nacl.gyp
new file mode 100644
index 0000000..e375dc5
--- /dev/null
+++ b/testing/gtest_nacl.gyp
@@ -0,0 +1,90 @@
+# Copyright 2014 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.
+
+{
+ 'variables': {
+ 'chromium_code': 1,
+ },
+ 'includes': [
+ '../build/common_untrusted.gypi',
+ 'gtest.gypi',
+ ],
+ 'conditions': [
+ ['disable_nacl==0 and disable_nacl_untrusted==0', {
+ 'targets': [
+ {
+ 'target_name': 'gtest_nacl',
+ 'type': 'none',
+ 'variables': {
+ 'nlib_target': 'libgtest_nacl.a',
+ 'build_glibc': 0,
+ 'build_newlib': 0,
+ 'build_pnacl_newlib': 1,
+ },
+ 'sources': [
+ '<@(gtest_sources)',
+ ],
+ 'include_dirs': [
+ 'gtest',
+ 'gtest/include',
+ ],
+ 'defines': [
+ # In order to allow regex matches in gtest to be shared between
+ # Windows and other systems, we tell gtest to always use it's
+ # internal engine.
+ 'GTEST_HAS_POSIX_RE=0',
+ 'GTEST_LANG_CXX11=0',
+ # gtest isn't able to figure out when RTTI is disabled for gcc
+ # versions older than 4.3.2, and assumes it's enabled. Our Mac
+ # and Linux builds disable RTTI, and cannot guarantee that the
+ # compiler will be 4.3.2. or newer. The Mac, for example, uses
+ # 4.2.1 as that is the latest available on that platform. gtest
+ # must be instructed that RTTI is disabled here, and for any
+ # direct dependents that might include gtest headers.
+ 'GTEST_HAS_RTTI=0',
+ ],
+ 'all_dependent_settings': {
+ 'defines': [
+ 'GTEST_HAS_POSIX_RE=0',
+ 'GTEST_LANG_CXX11=0',
+ ],
+ 'link_flags': [
+ '-lgtest_nacl',
+ ],
+ },
+ 'direct_dependent_settings': {
+ 'defines': [
+ 'UNIT_TEST',
+ 'GTEST_HAS_RTTI=0',
+ ],
+ 'include_dirs': [
+ 'gtest/include', # So that gtest headers can find themselves.
+ ],
+ },
+ },
+ {
+ 'target_name': 'gtest_main_nacl',
+ 'type': 'none',
+ 'variables': {
+ 'nlib_target': 'libgtest_main_nacl.a',
+ 'build_glibc': 0,
+ 'build_newlib': 0,
+ 'build_pnacl_newlib': 1,
+ },
+ 'dependencies': [
+ 'gtest_nacl',
+ ],
+ 'sources': [
+ 'gtest/src/gtest_main.cc',
+ ],
+ 'all_dependent_settings': {
+ 'link_flags': [
+ '-lgtest_main_nacl',
+ ],
+ },
+ },
+ ],
+ }],
+ ],
+}
diff --git a/testing/iossim/OWNERS b/testing/iossim/OWNERS
new file mode 100644
index 0000000..7f8c2f8
--- /dev/null
+++ b/testing/iossim/OWNERS
@@ -0,0 +1,3 @@
+lliabraa@chromium.org
+rohitrao@chromium.org
+stuartmorgan@chromium.org
diff --git a/testing/iossim/iossim.gyp b/testing/iossim/iossim.gyp
new file mode 100644
index 0000000..a8ad603
--- /dev/null
+++ b/testing/iossim/iossim.gyp
@@ -0,0 +1,162 @@
+# Copyright (c) 2012 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.
+
+{
+ 'conditions': [
+ ['OS!="ios" or "<(GENERATOR)"=="ninja"', {
+ 'targets': [
+ {
+ 'target_name': 'iossim',
+ 'toolsets': ['host'],
+ 'type': 'executable',
+ 'variables': {
+ 'developer_dir': '<!(xcode-select -print-path)',
+ # TODO(lliabraa): Once all builders are on Xcode 6 this variable can
+ # be removed and the actions gated by this variable can be run by
+ # default (crbug.com/385030).
+ 'xcode_version': '<!(xcodebuild -version | grep Xcode | awk \'{print $2}\')',
+ },
+ 'conditions': [
+ ['xcode_version>="6.0"', {
+ 'variables': {
+ 'iphone_sim_path': '<(developer_dir)/../SharedFrameworks',
+ },
+ 'defines': [
+ 'IOSSIM_USE_XCODE_6',
+ ],
+ 'xcode_settings': {
+ # The CoreSimulator.h file generated by class-dump defines a
+ # property of type |NSString*| and a setter for the property
+ # that takes a parameter of type |id|. This type mismatch causes
+ # a compiler warning, so turn off -Werror.
+ 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO',
+ },
+ 'actions': [
+ {
+ 'action_name': 'generate_dvt_foundation_header',
+ 'inputs': [
+ '<(iphone_sim_path)/DVTFoundation.framework/Versions/Current/DVTFoundation',
+ '<(PRODUCT_DIR)/class-dump',
+ ],
+ 'outputs': [
+ '<(INTERMEDIATE_DIR)/iossim/DVTFoundation.h'
+ ],
+ 'action': [
+ # Actions don't provide a way to redirect stdout, so a custom
+ # script is invoked that will execute the first argument and
+ # write the output to the file specified as the second argument.
+ # -I sorts classes, categories, and protocols by inheritance.
+ # -C <regex> only displays classes matching regular expression.
+ './redirect-stdout.sh',
+ '<(PRODUCT_DIR)/class-dump -CDVTStackBacktrace|DVTInvalidation|DVTMixIn <(iphone_sim_path)/DVTFoundation.framework',
+ '<(INTERMEDIATE_DIR)/iossim/DVTFoundation.h',
+ ],
+ 'message': 'Generating DVTFoundation.h',
+ },
+ {
+ 'action_name': 'generate_dvt_core_simulator',
+ 'inputs': [
+ '<(developer_dir)/Library/PrivateFrameworks/CoreSimulator.framework/Versions/Current/CoreSimulator',
+ '<(PRODUCT_DIR)/class-dump',
+ ],
+ 'outputs': [
+ '<(INTERMEDIATE_DIR)/iossim/CoreSimulator.h'
+ ],
+ 'action': [
+ # Actions don't provide a way to redirect stdout, so a custom
+ # script is invoked that will execute the first argument and
+ # write the output to the file specified as the second argument.
+ # -I sorts classes, categories, and protocols by inheritance.
+ # -C <regex> only displays classes matching regular expression.
+ './redirect-stdout.sh',
+ '<(PRODUCT_DIR)/class-dump -CSim <(developer_dir)/Library/PrivateFrameworks/CoreSimulator.framework',
+ '<(INTERMEDIATE_DIR)/iossim/CoreSimulator.h',
+ ],
+ 'message': 'Generating CoreSimulator.h',
+ },
+ ], # actions
+ }, { # else: xcode_version<"6.0"
+ 'variables': {
+ 'iphone_sim_path': '<(developer_dir)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks',
+ },
+ }], # xcode_version
+ ], # conditions
+ 'dependencies': [
+ 'third_party/class-dump/class-dump.gyp:class-dump#host',
+ ],
+ 'include_dirs': [
+ '<(INTERMEDIATE_DIR)/iossim',
+ ],
+ 'sources': [
+ 'iossim.mm',
+ '<(INTERMEDIATE_DIR)/iossim/iPhoneSimulatorRemoteClient.h',
+ ],
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_dvt_iphone_sim_header',
+ 'inputs': [
+ '<(iphone_sim_path)/DVTiPhoneSimulatorRemoteClient.framework/Versions/Current/DVTiPhoneSimulatorRemoteClient',
+ '<(PRODUCT_DIR)/class-dump',
+ ],
+ 'outputs': [
+ '<(INTERMEDIATE_DIR)/iossim/DVTiPhoneSimulatorRemoteClient.h'
+ ],
+ 'action': [
+ # Actions don't provide a way to redirect stdout, so a custom
+ # script is invoked that will execute the first argument and
+ # write the output to the file specified as the second argument.
+ # -I sorts classes, categories, and protocols by inheritance.
+ # -C <regex> only displays classes matching regular expression.
+ './redirect-stdout.sh',
+ '<(PRODUCT_DIR)/class-dump -I -CiPhoneSimulator <(iphone_sim_path)/DVTiPhoneSimulatorRemoteClient.framework',
+ '<(INTERMEDIATE_DIR)/iossim/DVTiPhoneSimulatorRemoteClient.h',
+ ],
+ 'message': 'Generating DVTiPhoneSimulatorRemoteClient.h',
+ },
+ ], # actions
+ 'xcode_settings': {
+ 'ARCHS': ['x86_64'],
+ 'WARNING_CFLAGS': [
+ '-Wno-objc-property-no-attribute',
+ ],
+ },
+ },
+ ],
+ }, { # else, OS=="ios" and "<(GENERATOR)"!="ninja"
+ 'variables': {
+ 'ninja_output_dir': 'ninja-iossim',
+ 'ninja_product_dir':
+ '$(SYMROOT)/<(ninja_output_dir)/<(CONFIGURATION_NAME)',
+ },
+ 'targets': [
+ {
+ 'target_name': 'iossim',
+ 'type': 'none',
+ 'variables': {
+ # Gyp to rerun
+ 're_run_targets': [
+ 'testing/iossim/iossim.gyp',
+ ],
+ },
+ 'includes': ['../../build/ios/mac_build.gypi'],
+ 'actions': [
+ {
+ 'action_name': 'compile iossim',
+ 'inputs': [],
+ 'outputs': [],
+ 'action': [
+ '<@(ninja_cmd)',
+ 'iossim',
+ ],
+ 'message': 'Generating the iossim executable',
+ },
+ ],
+ },
+ ],
+ }],
+ ],
+}
diff --git a/testing/iossim/iossim.mm b/testing/iossim/iossim.mm
new file mode 100644
index 0000000..93081e7
--- /dev/null
+++ b/testing/iossim/iossim.mm
@@ -0,0 +1,1017 @@
+// Copyright (c) 2012 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 <Foundation/Foundation.h>
+#include <asl.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+// An executable (iossim) that runs an app in the iOS Simulator.
+// Run 'iossim -h' for usage information.
+//
+// For best results, the iOS Simulator application should not be running when
+// iossim is invoked.
+//
+// Headers for iPhoneSimulatorRemoteClient and other frameworks used in this
+// tool are generated by class-dump, via GYP.
+// (class-dump is available at http://www.codethecode.com/projects/class-dump/)
+//
+// However, there are some forward declarations required to get things to
+// compile.
+
+// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed
+// (crbug.com/385030).
+#if defined(IOSSIM_USE_XCODE_6)
+@class DVTStackBacktrace;
+#import "DVTFoundation.h"
+#endif // IOSSIM_USE_XCODE_6
+
+@protocol OS_dispatch_queue
+@end
+@protocol OS_dispatch_source
+@end
+// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed
+// (crbug.com/385030).
+#if defined(IOSSIM_USE_XCODE_6)
+@protocol OS_xpc_object
+@end
+@protocol SimBridge;
+@class SimDeviceSet;
+@class SimDeviceType;
+@class SimRuntime;
+@class SimServiceConnectionManager;
+#import "CoreSimulator.h"
+#endif // IOSSIM_USE_XCODE_6
+
+@interface DVTPlatform : NSObject
++ (BOOL)loadAllPlatformsReturningError:(id*)arg1;
+@end
+@class DTiPhoneSimulatorApplicationSpecifier;
+@class DTiPhoneSimulatorSession;
+@class DTiPhoneSimulatorSessionConfig;
+@class DTiPhoneSimulatorSystemRoot;
+@class DVTConfinementServiceConnection;
+@class DVTDispatchLock;
+@class DVTiPhoneSimulatorMessenger;
+@class DVTNotificationToken;
+@class DVTTask;
+// The DTiPhoneSimulatorSessionDelegate protocol is referenced
+// by the iPhoneSimulatorRemoteClient framework, but not defined in the object
+// file, so it must be defined here before importing the generated
+// iPhoneSimulatorRemoteClient.h file.
+@protocol DTiPhoneSimulatorSessionDelegate
+- (void)session:(DTiPhoneSimulatorSession*)session
+ didEndWithError:(NSError*)error;
+- (void)session:(DTiPhoneSimulatorSession*)session
+ didStart:(BOOL)started
+ withError:(NSError*)error;
+@end
+#import "DVTiPhoneSimulatorRemoteClient.h"
+
+// An undocumented system log key included in messages from launchd. The value
+// is the PID of the process the message is about (as opposed to launchd's PID).
+#define ASL_KEY_REF_PID "RefPID"
+
+namespace {
+
+// Name of environment variables that control the user's home directory in the
+// simulator.
+const char* const kUserHomeEnvVariable = "CFFIXED_USER_HOME";
+const char* const kHomeEnvVariable = "HOME";
+
+// Device family codes for iPhone and iPad.
+const int kIPhoneFamily = 1;
+const int kIPadFamily = 2;
+
+// Max number of seconds to wait for the simulator session to start.
+// This timeout must allow time to start up iOS Simulator, install the app
+// and perform any other black magic that is encoded in the
+// iPhoneSimulatorRemoteClient framework to kick things off. Normal start up
+// time is only a couple seconds but machine load, disk caches, etc., can all
+// affect startup time in the wild so the timeout needs to be fairly generous.
+// If this timeout occurs iossim will likely exit with non-zero status; the
+// exception being if the app is invoked and completes execution before the
+// session is started (this case is handled in session:didStart:withError).
+const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30;
+
+// While the simulated app is running, its stdout is redirected to a file which
+// is polled by iossim and written to iossim's stdout using the following
+// polling interval.
+const NSTimeInterval kOutputPollIntervalSeconds = 0.1;
+
+NSString* const kDVTFoundationRelativePath =
+ @"../SharedFrameworks/DVTFoundation.framework";
+NSString* const kDevToolsFoundationRelativePath =
+ @"../OtherFrameworks/DevToolsFoundation.framework";
+NSString* const kSimulatorRelativePath =
+ @"Platforms/iPhoneSimulator.platform/Developer/Applications/"
+ @"iPhone Simulator.app";
+
+// Simulator Error String Key. This can be found by looking in the Simulator's
+// Localizable.strings files.
+NSString* const kSimulatorAppQuitErrorKey = @"The simulated application quit.";
+
+const char* gToolName = "iossim";
+
+// Exit status codes.
+const int kExitSuccess = EXIT_SUCCESS;
+const int kExitFailure = EXIT_FAILURE;
+const int kExitInvalidArguments = 2;
+const int kExitInitializationFailure = 3;
+const int kExitAppFailedToStart = 4;
+const int kExitAppCrashed = 5;
+const int kExitUnsupportedXcodeVersion = 6;
+
+void LogError(NSString* format, ...) {
+ va_list list;
+ va_start(list, format);
+
+ NSString* message =
+ [[[NSString alloc] initWithFormat:format arguments:list] autorelease];
+
+ fprintf(stderr, "%s: ERROR: %s\n", gToolName, [message UTF8String]);
+ fflush(stderr);
+
+ va_end(list);
+}
+
+void LogWarning(NSString* format, ...) {
+ va_list list;
+ va_start(list, format);
+
+ NSString* message =
+ [[[NSString alloc] initWithFormat:format arguments:list] autorelease];
+
+ fprintf(stderr, "%s: WARNING: %s\n", gToolName, [message UTF8String]);
+ fflush(stderr);
+
+ va_end(list);
+}
+
+// Helper to find a class by name and die if it isn't found.
+Class FindClassByName(NSString* nameOfClass) {
+ Class theClass = NSClassFromString(nameOfClass);
+ if (!theClass) {
+ LogError(@"Failed to find class %@ at runtime.", nameOfClass);
+ exit(kExitInitializationFailure);
+ }
+ return theClass;
+}
+
+// Returns the a NSString containing the stdout from running an NSTask that
+// launches |toolPath| with th given command line |args|.
+NSString* GetOutputFromTask(NSString* toolPath, NSArray* args) {
+ NSTask* task = [[[NSTask alloc] init] autorelease];
+ [task setLaunchPath:toolPath];
+ [task setArguments:args];
+ NSPipe* outputPipe = [NSPipe pipe];
+ [task setStandardOutput:outputPipe];
+ NSFileHandle* outputFile = [outputPipe fileHandleForReading];
+
+ [task launch];
+ NSData* outputData = [outputFile readDataToEndOfFile];
+ [task waitUntilExit];
+ if ([task isRunning]) {
+ LogError(@"Task '%@ %@' is still running.",
+ toolPath,
+ [args componentsJoinedByString:@" "]);
+ return nil;
+ } else if ([task terminationStatus]) {
+ LogError(@"Task '%@ %@' exited with return code %d.",
+ toolPath,
+ [args componentsJoinedByString:@" "],
+ [task terminationStatus]);
+ return nil;
+ }
+ return [[[NSString alloc] initWithData:outputData
+ encoding:NSUTF8StringEncoding] autorelease];
+}
+
+// Finds the Xcode version via xcodebuild -version. Output from xcodebuild is
+// expected to look like:
+// Xcode <version>
+// Build version 5B130a
+// where <version> is the string returned by this function (e.g. 6.0).
+NSString* FindXcodeVersion() {
+ NSString* output = GetOutputFromTask(@"/usr/bin/xcodebuild",
+ @[ @"-version" ]);
+ // Scan past the "Xcode ", then scan the rest of the line into |version|.
+ NSScanner* scanner = [NSScanner scannerWithString:output];
+ BOOL valid = [scanner scanString:@"Xcode " intoString:NULL];
+ NSString* version;
+ valid =
+ [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
+ intoString:&version];
+ if (!valid) {
+ LogError(@"Unable to find Xcode version. 'xcodebuild -version' "
+ @"returned \n%@", output);
+ return nil;
+ }
+ return version;
+}
+
+// Returns true if iossim is running with Xcode 6 or later installed on the
+// host.
+BOOL IsRunningWithXcode6OrLater() {
+ static NSString* xcodeVersion = FindXcodeVersion();
+ if (!xcodeVersion) {
+ return false;
+ }
+ NSArray* components = [xcodeVersion componentsSeparatedByString:@"."];
+ if ([components count] < 1) {
+ return false;
+ }
+ NSInteger majorVersion = [[components objectAtIndex:0] integerValue];
+ return majorVersion >= 6;
+}
+
+// Prints supported devices and SDKs.
+void PrintSupportedDevices() {
+ if (IsRunningWithXcode6OrLater()) {
+#if defined(IOSSIM_USE_XCODE_6)
+ printf("Supported device/SDK combinations:\n");
+ Class simDeviceSetClass = FindClassByName(@"SimDeviceSet");
+ id deviceSet =
+ [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]];
+ for (id simDevice in [deviceSet availableDevices]) {
+ NSString* deviceInfo =
+ [NSString stringWithFormat:@" -d '%@' -s '%@'\n",
+ [simDevice name], [[simDevice runtime] versionString]];
+ printf("%s", [deviceInfo UTF8String]);
+ }
+#endif // IOSSIM_USE_XCODE_6
+ } else {
+ printf("Supported SDK versions:\n");
+ Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot");
+ for (id root in [rootClass knownRoots]) {
+ printf(" '%s'\n", [[root sdkVersion] UTF8String]);
+ }
+ // This is the list of devices supported on Xcode 5.1.x.
+ printf("Supported devices:\n");
+ printf(" 'iPhone'\n");
+ printf(" 'iPhone Retina (3.5-inch)'\n");
+ printf(" 'iPhone Retina (4-inch)'\n");
+ printf(" 'iPhone Retina (4-inch 64-bit)'\n");
+ printf(" 'iPad'\n");
+ printf(" 'iPad Retina'\n");
+ printf(" 'iPad Retina (64-bit)'\n");
+ }
+}
+} // namespace
+
+// A delegate that is called when the simulated app is started or ended in the
+// simulator.
+@interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> {
+ @private
+ NSString* stdioPath_;
+ NSString* developerDir_;
+ NSString* simulatorHome_;
+ NSThread* outputThread_;
+ NSBundle* simulatorBundle_;
+ BOOL appRunning_;
+}
+@end
+
+// An implementation that copies the simulated app's stdio to stdout of this
+// executable. While it would be nice to get stdout and stderr independently
+// from iOS Simulator, issues like I/O buffering and interleaved output
+// between iOS Simulator and the app would cause iossim to display things out
+// of order here. Printing all output to a single file keeps the order correct.
+// Instances of this classe should be initialized with the location of the
+// simulated app's output file. When the simulated app starts, a thread is
+// started which handles copying data from the simulated app's output file to
+// the stdout of this executable.
+@implementation SimulatorDelegate
+
+// Specifies the file locations of the simulated app's stdout and stderr.
+- (SimulatorDelegate*)initWithStdioPath:(NSString*)stdioPath
+ developerDir:(NSString*)developerDir
+ simulatorHome:(NSString*)simulatorHome {
+ self = [super init];
+ if (self) {
+ stdioPath_ = [stdioPath copy];
+ developerDir_ = [developerDir copy];
+ simulatorHome_ = [simulatorHome copy];
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ [stdioPath_ release];
+ [developerDir_ release];
+ [simulatorBundle_ release];
+ [super dealloc];
+}
+
+// Reads data from the simulated app's output and writes it to stdout. This
+// method blocks, so it should be called in a separate thread. The iOS
+// Simulator takes a file path for the simulated app's stdout and stderr, but
+// this path isn't always available (e.g. when the stdout is Xcode's build
+// window). As a workaround, iossim creates a temp file to hold output, which
+// this method reads and copies to stdout.
+- (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_];
+ if (IsRunningWithXcode6OrLater()) {
+#if defined(IOSSIM_USE_XCODE_6)
+ // With iOS 8 simulators on Xcode 6, the app output is relative to the
+ // simulator's data directory.
+ if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) {
+ NSString* dataPath = session.sessionConfig.device.dataPath;
+ NSString* appOutput =
+ [dataPath stringByAppendingPathComponent:stdioPath_];
+ simio = [NSFileHandle fileHandleForReadingAtPath:appOutput];
+ }
+#endif // IOSSIM_USE_XCODE_6
+ }
+ NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput];
+ // Copy data to stdout/stderr while the app is running.
+ while (appRunning_) {
+ NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init];
+ [standardOutput writeData:[simio readDataToEndOfFile]];
+ [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds];
+ [innerPool drain];
+ }
+
+ // Once the app is no longer running, copy any data that was written during
+ // the last sleep cycle.
+ [standardOutput writeData:[simio readDataToEndOfFile]];
+
+ [pool drain];
+}
+
+// Fetches a localized error string from the Simulator.
+- (NSString *)localizedSimulatorErrorString:(NSString*)stringKey {
+ // Lazy load of the simulator bundle.
+ if (simulatorBundle_ == nil) {
+ NSString* simulatorPath = [developerDir_
+ stringByAppendingPathComponent:kSimulatorRelativePath];
+ simulatorBundle_ = [NSBundle bundleWithPath:simulatorPath];
+ }
+ NSString *localizedStr =
+ [simulatorBundle_ localizedStringForKey:stringKey
+ value:nil
+ table:nil];
+ if ([localizedStr length])
+ return localizedStr;
+ // Failed to get a value, follow Cocoa conventions and use the key as the
+ // string.
+ return stringKey;
+}
+
+- (void)session:(DTiPhoneSimulatorSession*)session
+ didStart:(BOOL)started
+ withError:(NSError*)error {
+ if (!started) {
+ // If the test executes very quickly (<30ms), the SimulatorDelegate may not
+ // get the initial session:started:withError: message indicating successful
+ // startup of the simulated app. Instead the delegate will get a
+ // session:started:withError: message after the timeout has elapsed. To
+ // account for this case, check if the simulated app's stdio file was
+ // ever created and if it exists dump it to stdout and return success.
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+ if ([fileManager fileExistsAtPath:stdioPath_]) {
+ appRunning_ = NO;
+ [self tailOutputForSession:session];
+ // Note that exiting in this state leaves a process running
+ // (e.g. /.../iPhoneSimulator4.3.sdk/usr/libexec/installd -t 30) that will
+ // prevent future simulator sessions from being started for 30 seconds
+ // unless the iOS Simulator application is killed altogether.
+ [self session:session didEndWithError:nil];
+
+ // session:didEndWithError should not return (because it exits) so
+ // the execution path should never get here.
+ exit(kExitFailure);
+ }
+
+ LogError(@"Simulator failed to start: \"%@\" (%@:%ld)",
+ [error localizedDescription],
+ [error domain], static_cast<long int>([error code]));
+ PrintSupportedDevices();
+ exit(kExitAppFailedToStart);
+ }
+
+ // Start a thread to write contents of outputPath to stdout.
+ appRunning_ = YES;
+ outputThread_ =
+ [[NSThread alloc] initWithTarget:self
+ selector:@selector(tailOutputForSession:)
+ object:session];
+ [outputThread_ start];
+}
+
+- (void)session:(DTiPhoneSimulatorSession*)session
+ didEndWithError:(NSError*)error {
+ appRunning_ = NO;
+ // Wait for the output thread to finish copying data to stdout.
+ if (outputThread_) {
+ while (![outputThread_ isFinished]) {
+ [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds];
+ }
+ [outputThread_ release];
+ outputThread_ = nil;
+ }
+
+ if (error) {
+ // There appears to be a race condition where sometimes the simulator
+ // framework will end with an error, but the error is that the simulated
+ // app cleanly shut down; try to trap this error and don't fail the
+ // simulator run.
+ NSString* localizedDescription = [error localizedDescription];
+ NSString* ignorableErrorStr =
+ [self localizedSimulatorErrorString:kSimulatorAppQuitErrorKey];
+ if ([ignorableErrorStr isEqual:localizedDescription]) {
+ LogWarning(@"Ignoring that Simulator ended with: \"%@\" (%@:%ld)",
+ localizedDescription, [error domain],
+ static_cast<long int>([error code]));
+ } else {
+ LogError(@"Simulator ended with error: \"%@\" (%@:%ld)",
+ localizedDescription, [error domain],
+ static_cast<long int>([error code]));
+ exit(kExitFailure);
+ }
+ }
+
+ // Try to determine if the simulated app crashed or quit with a non-zero
+ // status code. iOS Simluator handles things a bit differently depending on
+ // the version, so first determine the iOS version being used.
+ BOOL badEntryFound = NO;
+ NSString* versionString =
+ [[[session sessionConfig] simulatedSystemRoot] sdkVersion];
+ NSInteger majorVersion = [[[versionString componentsSeparatedByString:@"."]
+ objectAtIndex:0] intValue];
+ if (majorVersion <= 6) {
+ // In iOS 6 and before, logging from the simulated apps went to the main
+ // system logs, so use ASL to check if the simulated app exited abnormally
+ // by looking for system log messages from launchd that refer to the
+ // simulated app's PID. Limit query to messages in the last minute since
+ // PIDs are cyclical.
+ aslmsg query = asl_new(ASL_TYPE_QUERY);
+ asl_set_query(query, ASL_KEY_SENDER, "launchd",
+ ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_SUBSTRING);
+ char session_id[20];
+ if (snprintf(session_id, 20, "%d", [session simulatedApplicationPID]) < 0) {
+ LogError(@"Failed to get [session simulatedApplicationPID]");
+ exit(kExitFailure);
+ }
+ asl_set_query(query, ASL_KEY_REF_PID, session_id, ASL_QUERY_OP_EQUAL);
+ asl_set_query(query, ASL_KEY_TIME, "-1m", ASL_QUERY_OP_GREATER_EQUAL);
+
+ // Log any messages found, and take note of any messages that may indicate
+ // the app crashed or did not exit cleanly.
+ aslresponse response = asl_search(NULL, query);
+ aslmsg entry;
+ while ((entry = aslresponse_next(response)) != NULL) {
+ const char* message = asl_get(entry, ASL_KEY_MSG);
+ LogWarning(@"Console message: %s", message);
+ // Some messages are harmless, so don't trigger a failure for them.
+ if (strstr(message, "The following job tried to hijack the service"))
+ continue;
+ badEntryFound = YES;
+ }
+ } else {
+ // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the
+ // sandboxed system.log file for known errors.
+ NSString* path;
+ if (IsRunningWithXcode6OrLater()) {
+#if defined(IOSSIM_USE_XCODE_6)
+ NSString* dataPath = session.sessionConfig.device.dataPath;
+ path =
+ [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"];
+#endif // IOSSIM_USE_XCODE_6
+ } else {
+ NSString* relativePathToSystemLog =
+ [NSString stringWithFormat:
+ @"Library/Logs/iOS Simulator/%@/system.log", versionString];
+ path = [simulatorHome_
+ stringByAppendingPathComponent:relativePathToSystemLog];
+ }
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+ if ([fileManager fileExistsAtPath:path]) {
+ NSString* content =
+ [NSString stringWithContentsOfFile:path
+ encoding:NSUTF8StringEncoding
+ error:NULL];
+ NSArray* lines = [content componentsSeparatedByCharactersInSet:
+ [NSCharacterSet newlineCharacterSet]];
+ NSString* simulatedAppPID =
+ [NSString stringWithFormat:@"%d", session.simulatedApplicationPID];
+ for (NSString* line in lines) {
+ NSString* const kErrorString = @"Service exited with abnormal code:";
+ if ([line rangeOfString:kErrorString].location != NSNotFound &&
+ [line rangeOfString:simulatedAppPID].location != NSNotFound) {
+ LogWarning(@"Console message: %@", line);
+ badEntryFound = YES;
+ break;
+ }
+ }
+ // Remove the log file so subsequent invocations of iossim won't be
+ // looking at stale logs.
+ remove([path fileSystemRepresentation]);
+ } else {
+ LogWarning(@"Unable to find system log at '%@'.", path);
+ }
+ }
+
+ // If the query returned any nasty-looking results, iossim should exit with
+ // non-zero status.
+ if (badEntryFound) {
+ LogError(@"Simulated app crashed or exited with non-zero status");
+ exit(kExitAppCrashed);
+ }
+ exit(kExitSuccess);
+}
+@end
+
+namespace {
+
+// Finds the developer dir via xcode-select or the DEVELOPER_DIR environment
+// variable.
+NSString* FindDeveloperDir() {
+ // Check the env first.
+ NSDictionary* env = [[NSProcessInfo processInfo] environment];
+ NSString* developerDir = [env objectForKey:@"DEVELOPER_DIR"];
+ if ([developerDir length] > 0)
+ return developerDir;
+
+ // Go look for it via xcode-select.
+ NSString* output = GetOutputFromTask(@"/usr/bin/xcode-select",
+ @[ @"-print-path" ]);
+ output = [output stringByTrimmingCharactersInSet:
+ [NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ if ([output length] == 0)
+ output = nil;
+ return output;
+}
+
+// Loads the Simulator framework from the given developer dir.
+NSBundle* LoadSimulatorFramework(NSString* developerDir) {
+ // The Simulator framework depends on some of the other Xcode private
+ // frameworks; manually load them first so everything can be linked up.
+ NSString* dvtFoundationPath = [developerDir
+ stringByAppendingPathComponent:kDVTFoundationRelativePath];
+ NSBundle* dvtFoundationBundle =
+ [NSBundle bundleWithPath:dvtFoundationPath];
+ if (![dvtFoundationBundle load])
+ return nil;
+
+ NSString* devToolsFoundationPath = [developerDir
+ stringByAppendingPathComponent:kDevToolsFoundationRelativePath];
+ NSBundle* devToolsFoundationBundle =
+ [NSBundle bundleWithPath:devToolsFoundationPath];
+ if (![devToolsFoundationBundle load])
+ return nil;
+
+ // Prime DVTPlatform.
+ NSError* error;
+ Class DVTPlatformClass = FindClassByName(@"DVTPlatform");
+ if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) {
+ LogError(@"Unable to loadAllPlatformsReturningError. Error: %@",
+ [error localizedDescription]);
+ return nil;
+ }
+
+ // The path within the developer dir of the private Simulator frameworks.
+ NSString* simulatorFrameworkRelativePath;
+ if (IsRunningWithXcode6OrLater()) {
+ simulatorFrameworkRelativePath =
+ @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework";
+ NSString* const kCoreSimulatorRelativePath =
+ @"Library/PrivateFrameworks/CoreSimulator.framework";
+ NSString* coreSimulatorPath = [developerDir
+ stringByAppendingPathComponent:kCoreSimulatorRelativePath];
+ NSBundle* coreSimulatorBundle =
+ [NSBundle bundleWithPath:coreSimulatorPath];
+ if (![coreSimulatorBundle load])
+ return nil;
+ } else {
+ simulatorFrameworkRelativePath =
+ @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/"
+ @"DVTiPhoneSimulatorRemoteClient.framework";
+ }
+ NSString* simBundlePath = [developerDir
+ stringByAppendingPathComponent:simulatorFrameworkRelativePath];
+ NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath];
+ if (![simBundle load])
+ return nil;
+ return simBundle;
+}
+
+// Converts the given app path to an application spec, which requires an
+// absolute path.
+DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) {
+ Class applicationSpecifierClass =
+ FindClassByName(@"DTiPhoneSimulatorApplicationSpecifier");
+ if (![appPath isAbsolutePath]) {
+ NSString* cwd = [[NSFileManager defaultManager] currentDirectoryPath];
+ appPath = [cwd stringByAppendingPathComponent:appPath];
+ }
+ appPath = [appPath stringByStandardizingPath];
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+ if (![fileManager fileExistsAtPath:appPath]) {
+ LogError(@"File not found: %@", appPath);
+ exit(kExitInvalidArguments);
+ }
+ return [applicationSpecifierClass specifierWithApplicationPath:appPath];
+}
+
+// Returns the system root for the given SDK version. If sdkVersion is nil, the
+// default system root is returned. Will return nil if the sdkVersion is not
+// valid.
+DTiPhoneSimulatorSystemRoot* BuildSystemRoot(NSString* sdkVersion) {
+ Class systemRootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot");
+ DTiPhoneSimulatorSystemRoot* systemRoot = [systemRootClass defaultRoot];
+ if (sdkVersion)
+ systemRoot = [systemRootClass rootWithSDKVersion:sdkVersion];
+
+ return systemRoot;
+}
+
+// Builds a config object for starting the specified app.
+DTiPhoneSimulatorSessionConfig* BuildSessionConfig(
+ DTiPhoneSimulatorApplicationSpecifier* appSpec,
+ DTiPhoneSimulatorSystemRoot* systemRoot,
+ NSString* stdoutPath,
+ NSString* stderrPath,
+ NSArray* appArgs,
+ NSDictionary* appEnv,
+ NSNumber* deviceFamily,
+ NSString* deviceName) {
+ Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig");
+ DTiPhoneSimulatorSessionConfig* sessionConfig =
+ [[[sessionConfigClass alloc] init] autorelease];
+ sessionConfig.applicationToSimulateOnStart = appSpec;
+ sessionConfig.simulatedSystemRoot = systemRoot;
+ sessionConfig.localizedClientName = @"chromium";
+ sessionConfig.simulatedApplicationStdErrPath = stderrPath;
+ sessionConfig.simulatedApplicationStdOutPath = stdoutPath;
+ sessionConfig.simulatedApplicationLaunchArgs = appArgs;
+ sessionConfig.simulatedApplicationLaunchEnvironment = appEnv;
+ sessionConfig.simulatedDeviceInfoName = deviceName;
+ sessionConfig.simulatedDeviceFamily = deviceFamily;
+
+ if (IsRunningWithXcode6OrLater()) {
+#if defined(IOSSIM_USE_XCODE_6)
+ Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
+ id simDeviceType =
+ [simDeviceTypeClass supportedDeviceTypesByName][deviceName];
+ Class simRuntimeClass = FindClassByName(@"SimRuntime");
+ NSString* identifier = systemRoot.runtime.identifier;
+ id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier];
+
+ // Attempt to use an existing device, but create one if a suitable match
+ // can't be found. For example, if the simulator is running with a
+ // non-default home directory (e.g. via iossim's -u command line arg) then
+ // there won't be any devices so one will have to be created.
+ Class simDeviceSetClass = FindClassByName(@"SimDeviceSet");
+ id deviceSet =
+ [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]];
+ id simDevice = nil;
+ for (id device in [deviceSet availableDevices]) {
+ if ([device runtime] == simRuntime &&
+ [device deviceType] == simDeviceType) {
+ simDevice = device;
+ break;
+ }
+ }
+ if (!simDevice) {
+ NSError* error = nil;
+ // n.b. only the device name is necessary because the iOS Simulator menu
+ // already splits devices by runtime version.
+ NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName];
+ simDevice = [deviceSet createDeviceWithType:simDeviceType
+ runtime:simRuntime
+ name:name
+ error:&error];
+ if (error) {
+ LogError(@"Failed to create device: %@", error);
+ exit(kExitInitializationFailure);
+ }
+ }
+ sessionConfig.device = simDevice;
+#endif // IOSSIM_USE_XCODE_6
+ }
+ return sessionConfig;
+}
+
+// Builds a simulator session that will use the given delegate.
+DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) {
+ Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession");
+ DTiPhoneSimulatorSession* session =
+ [[[sessionClass alloc] init] autorelease];
+ session.delegate = delegate;
+ return session;
+}
+
+// Creates a temporary directory with a unique name based on the provided
+// template. The template should not contain any path separators and be suffixed
+// with X's, which will be substituted with a unique alphanumeric string (see
+// 'man mkdtemp' for details). The directory will be created as a subdirectory
+// of NSTemporaryDirectory(). For example, if dirNameTemplate is 'test-XXX',
+// this method would return something like '/path/to/tempdir/test-3n2'.
+//
+// Returns the absolute path of the newly-created directory, or nill if unable
+// to create a unique directory.
+NSString* CreateTempDirectory(NSString* dirNameTemplate) {
+ NSString* fullPathTemplate =
+ [NSTemporaryDirectory() stringByAppendingPathComponent:dirNameTemplate];
+ char* fullPath = mkdtemp(const_cast<char*>([fullPathTemplate UTF8String]));
+ if (fullPath == NULL)
+ return nil;
+
+ return [NSString stringWithUTF8String:fullPath];
+}
+
+// Creates the necessary directory structure under the given user home directory
+// path.
+// Returns YES if successful, NO if unable to create the directories.
+BOOL CreateHomeDirSubDirs(NSString* userHomePath) {
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+
+ // Create user home and subdirectories.
+ NSArray* subDirsToCreate = [NSArray arrayWithObjects:
+ @"Documents",
+ @"Library/Caches",
+ @"Library/Preferences",
+ nil];
+ for (NSString* subDir in subDirsToCreate) {
+ NSString* path = [userHomePath stringByAppendingPathComponent:subDir];
+ NSError* error;
+ if (![fileManager createDirectoryAtPath:path
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:&error]) {
+ LogError(@"Unable to create directory: %@. Error: %@",
+ path, [error localizedDescription]);
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+// Creates the necessary directory structure under the given user home directory
+// path, then sets the path in the appropriate environment variable.
+// Returns YES if successful, NO if unable to create or initialize the given
+// directory.
+BOOL InitializeSimulatorUserHome(NSString* userHomePath) {
+ if (!CreateHomeDirSubDirs(userHomePath))
+ return NO;
+
+ // Update the environment to use the specified directory as the user home
+ // directory.
+ // Note: the third param of setenv specifies whether or not to overwrite the
+ // variable's value if it has already been set.
+ if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) ||
+ (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) {
+ LogError(@"Unable to set environment variables for home directory.");
+ return NO;
+ }
+
+ return YES;
+}
+
+// Performs a case-insensitive search to see if |stringToSearch| begins with
+// |prefixToFind|. Returns true if a match is found.
+BOOL CaseInsensitivePrefixSearch(NSString* stringToSearch,
+ NSString* prefixToFind) {
+ NSStringCompareOptions options = (NSAnchoredSearch | NSCaseInsensitiveSearch);
+ NSRange range = [stringToSearch rangeOfString:prefixToFind
+ options:options];
+ return range.location != NSNotFound;
+}
+
+// Prints the usage information to stderr.
+void PrintUsage() {
+ fprintf(stderr, "Usage: iossim [-d device] [-s sdkVersion] [-u homeDir] "
+ "[-e envKey=value]* [-t startupTimeout] <appPath> [<appArgs>]\n"
+ " where <appPath> is the path to the .app directory and appArgs are any"
+ " arguments to send the simulated app.\n"
+ "\n"
+ "Options:\n"
+ " -d Specifies the device (must be one of the values from the iOS"
+ " Simulator's Hardware -> Device menu. Defaults to 'iPhone'.\n"
+ " -s Specifies the SDK version to use (e.g '4.3')."
+ " Will use system default if not specified.\n"
+ " -u Specifies a user home directory for the simulator."
+ " Will create a new directory if not specified.\n"
+ " -e Specifies an environment key=value pair that will be"
+ " set in the simulated application's environment.\n"
+ " -t Specifies the session startup timeout (in seconds)."
+ " Defaults to %d.\n"
+ " -l List supported devices and iOS versions.\n",
+ static_cast<int>(kDefaultSessionStartTimeoutSeconds));
+}
+} // namespace
+
+void EnsureSupportForCurrentXcodeVersion() {
+ if (IsRunningWithXcode6OrLater()) {
+#if !IOSSIM_USE_XCODE_6
+ LogError(@"Running on Xcode 6, but Xcode 6 support was not compiled in.");
+ exit(kExitUnsupportedXcodeVersion);
+#endif // IOSSIM_USE_XCODE_6
+ }
+}
+
+int main(int argc, char* const argv[]) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ EnsureSupportForCurrentXcodeVersion();
+
+ // basename() may modify the passed in string and it returns a pointer to an
+ // internal buffer. Give it a copy to modify, and copy what it returns.
+ char* worker = strdup(argv[0]);
+ char* toolName = basename(worker);
+ if (toolName != NULL) {
+ toolName = strdup(toolName);
+ if (toolName != NULL)
+ gToolName = toolName;
+ }
+ if (worker != NULL)
+ free(worker);
+
+ NSString* appPath = nil;
+ NSString* appName = nil;
+ NSString* sdkVersion = nil;
+ NSString* deviceName = IsRunningWithXcode6OrLater() ? @"iPhone 5" : @"iPhone";
+ NSString* simHomePath = nil;
+ NSMutableArray* appArgs = [NSMutableArray array];
+ NSMutableDictionary* appEnv = [NSMutableDictionary dictionary];
+ NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds;
+
+ NSString* developerDir = FindDeveloperDir();
+ if (!developerDir) {
+ LogError(@"Unable to find developer directory.");
+ exit(kExitInitializationFailure);
+ }
+
+ NSBundle* simulatorFramework = LoadSimulatorFramework(developerDir);
+ if (!simulatorFramework) {
+ LogError(@"Failed to load the Simulator Framework.");
+ exit(kExitInitializationFailure);
+ }
+
+ // Parse the optional arguments
+ int c;
+ while ((c = getopt(argc, argv, "hs:d:u:e:t:l")) != -1) {
+ switch (c) {
+ case 's':
+ sdkVersion = [NSString stringWithUTF8String:optarg];
+ break;
+ case 'd':
+ deviceName = [NSString stringWithUTF8String:optarg];
+ break;
+ case 'u':
+ simHomePath = [[NSFileManager defaultManager]
+ stringWithFileSystemRepresentation:optarg length:strlen(optarg)];
+ break;
+ case 'e': {
+ NSString* envLine = [NSString stringWithUTF8String:optarg];
+ NSRange range = [envLine rangeOfString:@"="];
+ if (range.location == NSNotFound) {
+ LogError(@"Invalid key=value argument for -e.");
+ PrintUsage();
+ exit(kExitInvalidArguments);
+ }
+ NSString* key = [envLine substringToIndex:range.location];
+ NSString* value = [envLine substringFromIndex:(range.location + 1)];
+ [appEnv setObject:value forKey:key];
+ }
+ break;
+ case 't': {
+ int timeout = atoi(optarg);
+ if (timeout > 0) {
+ sessionStartTimeout = static_cast<NSTimeInterval>(timeout);
+ } else {
+ LogError(@"Invalid startup timeout (%s).", optarg);
+ PrintUsage();
+ exit(kExitInvalidArguments);
+ }
+ }
+ break;
+ case 'l':
+ PrintSupportedDevices();
+ exit(kExitSuccess);
+ break;
+ case 'h':
+ PrintUsage();
+ exit(kExitSuccess);
+ default:
+ PrintUsage();
+ exit(kExitInvalidArguments);
+ }
+ }
+
+ // There should be at least one arg left, specifying the app path. Any
+ // additional args are passed as arguments to the app.
+ if (optind < argc) {
+ appPath = [[NSFileManager defaultManager]
+ stringWithFileSystemRepresentation:argv[optind]
+ length:strlen(argv[optind])];
+ appName = [appPath lastPathComponent];
+ while (++optind < argc) {
+ [appArgs addObject:[NSString stringWithUTF8String:argv[optind]]];
+ }
+ } else {
+ LogError(@"Unable to parse command line arguments.");
+ PrintUsage();
+ exit(kExitInvalidArguments);
+ }
+
+ // Make sure the app path provided is legit.
+ DTiPhoneSimulatorApplicationSpecifier* appSpec = BuildAppSpec(appPath);
+ if (!appSpec) {
+ LogError(@"Invalid app path: %@", appPath);
+ exit(kExitInitializationFailure);
+ }
+
+ // Make sure the SDK path provided is legit (or nil).
+ DTiPhoneSimulatorSystemRoot* systemRoot = BuildSystemRoot(sdkVersion);
+ if (!systemRoot) {
+ LogError(@"Invalid SDK version: %@", sdkVersion);
+ PrintSupportedDevices();
+ exit(kExitInitializationFailure);
+ }
+
+ // Get the paths for stdout and stderr so the simulated app's output will show
+ // up in the caller's stdout/stderr.
+ NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX");
+ NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"];
+
+ // Determine the deviceFamily based on the deviceName
+ NSNumber* deviceFamily = nil;
+ if (IsRunningWithXcode6OrLater()) {
+#if defined(IOSSIM_USE_XCODE_6)
+ Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
+ if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) {
+ LogError(@"Invalid device name: %@.", deviceName);
+ PrintSupportedDevices();
+ exit(kExitInvalidArguments);
+ }
+#endif // IOSSIM_USE_XCODE_6
+ } else {
+ if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) {
+ deviceFamily = [NSNumber numberWithInt:kIPhoneFamily];
+ } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) {
+ deviceFamily = [NSNumber numberWithInt:kIPadFamily];
+ }
+ else {
+ LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'",
+ deviceName);
+ exit(kExitInvalidArguments);
+ }
+ }
+
+ // Set up the user home directory for the simulator only if a non-default
+ // value was specified.
+ if (simHomePath) {
+ if (!InitializeSimulatorUserHome(simHomePath)) {
+ LogError(@"Unable to initialize home directory for simulator: %@",
+ simHomePath);
+ exit(kExitInitializationFailure);
+ }
+ } else {
+ simHomePath = NSHomeDirectory();
+ }
+
+ // Create the config and simulator session.
+ DTiPhoneSimulatorSessionConfig* config = BuildSessionConfig(appSpec,
+ systemRoot,
+ stdioPath,
+ stdioPath,
+ appArgs,
+ appEnv,
+ deviceFamily,
+ deviceName);
+ SimulatorDelegate* delegate =
+ [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath
+ developerDir:developerDir
+ simulatorHome:simHomePath] autorelease];
+ DTiPhoneSimulatorSession* session = BuildSession(delegate);
+
+ // Start the simulator session.
+ NSError* error;
+ BOOL started = [session requestStartWithConfig:config
+ timeout:sessionStartTimeout
+ error:&error];
+
+ // Spin the runtime indefinitely. When the delegate gets the message that the
+ // app has quit it will exit this program.
+ if (started) {
+ [[NSRunLoop mainRunLoop] run];
+ } else {
+ LogError(@"Simulator failed request to start: \"%@\" (%@:%ld)",
+ [error localizedDescription],
+ [error domain], static_cast<long int>([error code]));
+ }
+
+ // Note that this code is only executed if the simulator fails to start
+ // because once the main run loop is started, only the delegate calling
+ // exit() will end the program.
+ [pool drain];
+ return kExitFailure;
+}
diff --git a/testing/iossim/redirect-stdout.sh b/testing/iossim/redirect-stdout.sh
new file mode 100755
index 0000000..d6c3cf8
--- /dev/null
+++ b/testing/iossim/redirect-stdout.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# Copyright (c) 2012 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.
+#
+# This script executes the command given as the first argument, strips
+# cxx_destruct from stdout, and redirects the remaining stdout to the file given
+# as the second argument.
+#
+# Example: Write the text 'foo' to a file called out.txt:
+# RedirectStdout.sh "echo foo" out.txt
+#
+# This script is invoked from iossim.gyp in order to redirect the output of
+# class-dump to a file (because gyp actions don't support redirecting output).
+# This script also removes all lines with cxx_destruct. Perhaps newer versions
+# of class-dump will fix this issue. As of 3.5, 'cxx_destruct' still exists.
+
+if [ ${#} -ne 2 ] ; then
+ echo "usage: ${0} <command> <output file>"
+ exit 2
+fi
+
+$1 | sed /cxx_destruct/d > $2
diff --git a/testing/multiprocess_func_list.cc b/testing/multiprocess_func_list.cc
new file mode 100644
index 0000000..49ae07d
--- /dev/null
+++ b/testing/multiprocess_func_list.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 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.
+
+#include "multiprocess_func_list.h"
+
+#include <map>
+
+// Helper functions to maintain mapping of "test name"->test func.
+// The information is accessed via a global map.
+namespace multi_process_function_list {
+
+namespace {
+
+struct ProcessFunctions {
+ ProcessFunctions() : main(NULL), setup(NULL) {}
+ ProcessFunctions(TestMainFunctionPtr main, SetupFunctionPtr setup)
+ : main(main),
+ setup(setup) {
+ }
+ TestMainFunctionPtr main;
+ SetupFunctionPtr setup;
+};
+
+typedef std::map<std::string, ProcessFunctions> MultiProcessTestMap;
+
+// Retrieve a reference to the global 'func name' -> func ptr map.
+MultiProcessTestMap& GetMultiprocessFuncMap() {
+ static MultiProcessTestMap test_name_to_func_ptr_map;
+ return test_name_to_func_ptr_map;
+}
+
+} // namespace
+
+AppendMultiProcessTest::AppendMultiProcessTest(
+ std::string test_name,
+ TestMainFunctionPtr main_func_ptr,
+ SetupFunctionPtr setup_func_ptr) {
+ GetMultiprocessFuncMap()[test_name] =
+ ProcessFunctions(main_func_ptr, setup_func_ptr);
+}
+
+int InvokeChildProcessTest(std::string test_name) {
+ MultiProcessTestMap& func_lookup_table = GetMultiprocessFuncMap();
+ MultiProcessTestMap::iterator it = func_lookup_table.find(test_name);
+ if (it != func_lookup_table.end()) {
+ const ProcessFunctions& process_functions = it->second;
+ if (process_functions.setup)
+ (*process_functions.setup)();
+ if (process_functions.main)
+ return (*process_functions.main)();
+ }
+
+ return -1;
+}
+
+} // namespace multi_process_function_list
diff --git a/testing/multiprocess_func_list.h b/testing/multiprocess_func_list.h
new file mode 100644
index 0000000..f806d53
--- /dev/null
+++ b/testing/multiprocess_func_list.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 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.
+
+#ifndef TESTING_MULTIPROCESS_FUNC_LIST_H_
+#define TESTING_MULTIPROCESS_FUNC_LIST_H_
+
+#include <string>
+
+// This file provides the plumbing to register functions to be executed
+// as the main function of a child process in a multi-process test.
+// This complements the MultiProcessTest class which provides facilities
+// for launching such tests.
+//
+// The MULTIPROCESS_TEST_MAIN() macro registers a string -> func_ptr mapping
+// by creating a new global instance of the AppendMultiProcessTest() class
+// this means that by the time that we reach our main() function the mapping
+// is already in place.
+//
+// Example usage:
+// MULTIPROCESS_TEST_MAIN(a_test_func) {
+// // Code here runs in a child process.
+// return 0;
+// }
+//
+// The prototype of a_test_func is implicitly
+// int test_main_func_name();
+
+namespace multi_process_function_list {
+
+// Type for child process main functions.
+typedef int (*TestMainFunctionPtr)();
+
+// Type for child setup functions.
+typedef void (*SetupFunctionPtr)();
+
+// Helper class to append a test function to the global mapping.
+// Used by the MULTIPROCESS_TEST_MAIN macro.
+class AppendMultiProcessTest {
+ public:
+ // |main_func_ptr| is the main function that is run in the child process.
+ // |setup_func_ptr| is a function run when the global mapping is added.
+ AppendMultiProcessTest(std::string test_name,
+ TestMainFunctionPtr main_func_ptr,
+ SetupFunctionPtr setup_func_ptr);
+};
+
+// Invoke the main function of a test previously registered with
+// MULTIPROCESS_TEST_MAIN()
+int InvokeChildProcessTest(std::string test_name);
+
+// This macro creates a global MultiProcessTest::AppendMultiProcessTest object
+// whose constructor does the work of adding the global mapping.
+#define MULTIPROCESS_TEST_MAIN(test_main) \
+ MULTIPROCESS_TEST_MAIN_WITH_SETUP(test_main, NULL)
+
+// Same as above but lets callers specify a setup method that is run in the
+// child process, just before the main function is run. This facilitates
+// adding a generic one-time setup function for multiple tests.
+#define MULTIPROCESS_TEST_MAIN_WITH_SETUP(test_main, test_setup) \
+ int test_main(); \
+ namespace { \
+ multi_process_function_list::AppendMultiProcessTest \
+ AddMultiProcessTest##_##test_main(#test_main, (test_main), (test_setup)); \
+ } \
+ int test_main()
+
+} // namespace multi_process_function_list
+
+#endif // TESTING_MULTIPROCESS_FUNC_LIST_H_
diff --git a/testing/perf/BUILD.gn b/testing/perf/BUILD.gn
new file mode 100644
index 0000000..d158f19
--- /dev/null
+++ b/testing/perf/BUILD.gn
@@ -0,0 +1,8 @@
+# Copyright 2014 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.
+
+source_set("perf") {
+ sources = [ "perf_test.cc" ]
+ deps = [ "//base" ]
+}
diff --git a/testing/perf/perf_test.cc b/testing/perf/perf_test.cc
new file mode 100644
index 0000000..0d5abc0
--- /dev/null
+++ b/testing/perf/perf_test.cc
@@ -0,0 +1,204 @@
+// Copyright 2013 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.
+
+#include "testing/perf/perf_test.h"
+
+#include <stdio.h>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+
+namespace {
+
+std::string ResultsToString(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& values,
+ const std::string& prefix,
+ const std::string& suffix,
+ const std::string& units,
+ bool important) {
+ // <*>RESULT <graph_name>: <trace_name>= <value> <units>
+ // <*>RESULT <graph_name>: <trace_name>= {<mean>, <std deviation>} <units>
+ // <*>RESULT <graph_name>: <trace_name>= [<value>,value,value,...,] <units>
+ return base::StringPrintf("%sRESULT %s%s: %s= %s%s%s %s\n",
+ important ? "*" : "", measurement.c_str(), modifier.c_str(),
+ trace.c_str(), prefix.c_str(), values.c_str(), suffix.c_str(),
+ units.c_str());
+}
+
+void PrintResultsImpl(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& values,
+ const std::string& prefix,
+ const std::string& suffix,
+ const std::string& units,
+ bool important) {
+ fflush(stdout);
+ printf("%s", ResultsToString(measurement, modifier, trace, values,
+ prefix, suffix, units, important).c_str());
+ fflush(stdout);
+}
+
+} // namespace
+
+namespace perf_test {
+
+void PrintResult(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ size_t value,
+ const std::string& units,
+ bool important) {
+ PrintResultsImpl(measurement,
+ modifier,
+ trace,
+ base::UintToString(static_cast<unsigned int>(value)),
+ std::string(),
+ std::string(),
+ units,
+ important);
+}
+
+void PrintResult(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ double value,
+ const std::string& units,
+ bool important) {
+ PrintResultsImpl(measurement,
+ modifier,
+ trace,
+ base::DoubleToString(value),
+ std::string(),
+ std::string(),
+ units,
+ important);
+}
+
+void AppendResult(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ size_t value,
+ const std::string& units,
+ bool important) {
+ output += ResultsToString(
+ measurement,
+ modifier,
+ trace,
+ base::UintToString(static_cast<unsigned int>(value)),
+ std::string(),
+ std::string(),
+ units,
+ important);
+}
+
+void PrintResult(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& value,
+ const std::string& units,
+ bool important) {
+ PrintResultsImpl(measurement,
+ modifier,
+ trace,
+ value,
+ std::string(),
+ std::string(),
+ units,
+ important);
+}
+
+void AppendResult(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& value,
+ const std::string& units,
+ bool important) {
+ output += ResultsToString(measurement,
+ modifier,
+ trace,
+ value,
+ std::string(),
+ std::string(),
+ units,
+ important);
+}
+
+void PrintResultMeanAndError(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& mean_and_error,
+ const std::string& units,
+ bool important) {
+ PrintResultsImpl(measurement, modifier, trace, mean_and_error,
+ "{", "}", units, important);
+}
+
+void AppendResultMeanAndError(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& mean_and_error,
+ const std::string& units,
+ bool important) {
+ output += ResultsToString(measurement, modifier, trace, mean_and_error,
+ "{", "}", units, important);
+}
+
+void PrintResultList(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& values,
+ const std::string& units,
+ bool important) {
+ PrintResultsImpl(measurement, modifier, trace, values,
+ "[", "]", units, important);
+}
+
+void AppendResultList(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& values,
+ const std::string& units,
+ bool important) {
+ output += ResultsToString(measurement, modifier, trace, values,
+ "[", "]", units, important);
+}
+
+void PrintSystemCommitCharge(const std::string& test_name,
+ size_t charge,
+ bool important) {
+ PrintSystemCommitCharge(stdout, test_name, charge, important);
+}
+
+void PrintSystemCommitCharge(FILE* target,
+ const std::string& test_name,
+ size_t charge,
+ bool important) {
+ fprintf(target, "%s", SystemCommitChargeToString(test_name, charge,
+ important).c_str());
+}
+
+std::string SystemCommitChargeToString(const std::string& test_name,
+ size_t charge,
+ bool important) {
+ std::string trace_name(test_name);
+ std::string output;
+ AppendResult(output,
+ "commit_charge",
+ std::string(),
+ "cc" + trace_name,
+ charge,
+ "kb",
+ important);
+ return output;
+}
+
+} // namespace perf_test
diff --git a/testing/perf/perf_test.gyp b/testing/perf/perf_test.gyp
new file mode 100644
index 0000000..2065270
--- /dev/null
+++ b/testing/perf/perf_test.gyp
@@ -0,0 +1,18 @@
+# Copyright 2013 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.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'perf_test',
+ 'type': 'static_library',
+ 'sources': [
+ 'perf_test.cc',
+ ],
+ 'dependencies': [
+ '../../base/base.gyp:base',
+ ],
+ },
+ ],
+}
diff --git a/testing/perf/perf_test.h b/testing/perf/perf_test.h
new file mode 100644
index 0000000..36e2916
--- /dev/null
+++ b/testing/perf/perf_test.h
@@ -0,0 +1,116 @@
+// Copyright 2013 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.
+
+#ifndef TESTING_PERF_PERF_TEST_H_
+#define TESTING_PERF_PERF_TEST_H_
+
+#include <string>
+
+namespace perf_test {
+
+// Prints numerical information to stdout in a controlled format, for
+// post-processing. |measurement| is a description of the quantity being
+// measured, e.g. "vm_peak"; |modifier| is provided as a convenience and
+// will be appended directly to the name of the |measurement|, e.g.
+// "_browser"; |trace| is a description of the particular data point, e.g.
+// "reference"; |value| is the measured value; and |units| is a description
+// of the units of measure, e.g. "bytes". If |important| is true, the output
+// line will be specially marked, to notify the post-processor. The strings
+// may be empty. They should not contain any colons (:) or equals signs (=).
+// A typical post-processing step would be to produce graphs of the data
+// produced for various builds, using the combined |measurement| + |modifier|
+// string to specify a particular graph and the |trace| to identify a trace
+// (i.e., data series) on that graph.
+void PrintResult(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ size_t value,
+ const std::string& units,
+ bool important);
+void PrintResult(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ double value,
+ const std::string& units,
+ bool important);
+
+void AppendResult(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ size_t value,
+ const std::string& units,
+ bool important);
+
+// Like the above version of PrintResult(), but takes a std::string value
+// instead of a size_t.
+void PrintResult(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& value,
+ const std::string& units,
+ bool important);
+
+void AppendResult(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& value,
+ const std::string& units,
+ bool important);
+
+// Like PrintResult(), but prints a (mean, standard deviation) result pair.
+// The |<values>| should be two comma-separated numbers, the mean and
+// standard deviation (or other error metric) of the measurement.
+void PrintResultMeanAndError(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& mean_and_error,
+ const std::string& units,
+ bool important);
+
+void AppendResultMeanAndError(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& mean_and_error,
+ const std::string& units,
+ bool important);
+
+// Like PrintResult(), but prints an entire list of results. The |values|
+// will generally be a list of comma-separated numbers. A typical
+// post-processing step might produce plots of their mean and standard
+// deviation.
+void PrintResultList(const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& values,
+ const std::string& units,
+ bool important);
+
+void AppendResultList(std::string& output,
+ const std::string& measurement,
+ const std::string& modifier,
+ const std::string& trace,
+ const std::string& values,
+ const std::string& units,
+ bool important);
+
+// Prints memory commit charge stats for use by perf graphs.
+void PrintSystemCommitCharge(const std::string& test_name,
+ size_t charge,
+ bool important);
+
+void PrintSystemCommitCharge(FILE* target,
+ const std::string& test_name,
+ size_t charge,
+ bool important);
+
+std::string SystemCommitChargeToString(const std::string& test_name,
+ size_t charge,
+ bool important);
+
+} // namespace perf_test
+
+#endif // TESTING_PERF_PERF_TEST_H_
diff --git a/testing/platform_test.h b/testing/platform_test.h
new file mode 100644
index 0000000..04fc845
--- /dev/null
+++ b/testing/platform_test.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef TESTING_PLATFORM_TEST_H_
+#define TESTING_PLATFORM_TEST_H_
+
+#include <gtest/gtest.h>
+
+#if defined(GTEST_OS_MAC)
+#ifdef __OBJC__
+@class NSAutoreleasePool;
+#else
+class NSAutoreleasePool;
+#endif
+
+// The purpose of this class us to provide a hook for platform-specific
+// operations across unit tests. For example, on the Mac, it creates and
+// releases an outer NSAutoreleasePool for each test case. For now, it's only
+// implemented on the Mac. To enable this for another platform, just adjust
+// the #ifdefs and add a platform_test_<platform>.cc implementation file.
+class PlatformTest : public testing::Test {
+ public:
+ virtual ~PlatformTest();
+
+ protected:
+ PlatformTest();
+
+ private:
+ NSAutoreleasePool* pool_;
+};
+#else
+typedef testing::Test PlatformTest;
+#endif // GTEST_OS_MAC
+
+#endif // TESTING_PLATFORM_TEST_H_
diff --git a/testing/platform_test_ios.mm b/testing/platform_test_ios.mm
new file mode 100644
index 0000000..5162c1d
--- /dev/null
+++ b/testing/platform_test_ios.mm
@@ -0,0 +1,18 @@
+// Copyright 2014 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.
+
+#include "platform_test.h"
+
+#import <Foundation/Foundation.h>
+
+#include "coverage_util_ios.h"
+
+PlatformTest::PlatformTest()
+ : pool_([[NSAutoreleasePool alloc] init]) {
+}
+
+PlatformTest::~PlatformTest() {
+ [pool_ release];
+ coverage_util::FlushCoverageDataIfNecessary();
+}
diff --git a/testing/platform_test_mac.mm b/testing/platform_test_mac.mm
new file mode 100644
index 0000000..bd22cd5
--- /dev/null
+++ b/testing/platform_test_mac.mm
@@ -0,0 +1,15 @@
+// Copyright (c) 2006-2008 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.
+
+#include "platform_test.h"
+
+#import <Foundation/Foundation.h>
+
+PlatformTest::PlatformTest()
+ : pool_([[NSAutoreleasePool alloc] init]) {
+}
+
+PlatformTest::~PlatformTest() {
+ [pool_ release];
+}
diff --git a/testing/test_env.py b/testing/test_env.py
new file mode 100755
index 0000000..0729e17
--- /dev/null
+++ b/testing/test_env.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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.
+
+"""Sets environment variables needed to run a chromium unit test."""
+
+import os
+import stat
+import subprocess
+import sys
+
+# This is hardcoded to be src/ relative to this script.
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+CHROME_SANDBOX_ENV = 'CHROME_DEVEL_SANDBOX'
+CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox'
+
+
+def should_enable_sandbox(cmd, sandbox_path):
+ """Return a boolean indicating that the current slave is capable of using the
+ sandbox and should enable it. This should return True iff the slave is a
+ Linux host with the sandbox file present and configured correctly."""
+ if not (sys.platform.startswith('linux') and
+ os.path.exists(sandbox_path)):
+ return False
+
+ # Copy the check in tools/build/scripts/slave/runtest.py.
+ if '--lsan=1' in cmd:
+ return False
+
+ sandbox_stat = os.stat(sandbox_path)
+ if ((sandbox_stat.st_mode & stat.S_ISUID) and
+ (sandbox_stat.st_mode & stat.S_IRUSR) and
+ (sandbox_stat.st_mode & stat.S_IXUSR) and
+ (sandbox_stat.st_uid == 0)):
+ return True
+ return False
+
+
+def enable_sandbox_if_required(cmd, env, verbose=False):
+ """Checks enables the sandbox if it is required, otherwise it disables it."""
+ chrome_sandbox_path = env.get(CHROME_SANDBOX_ENV, CHROME_SANDBOX_PATH)
+
+ if should_enable_sandbox(cmd, chrome_sandbox_path):
+ if verbose:
+ print 'Enabling sandbox. Setting environment variable:'
+ print ' %s="%s"' % (CHROME_SANDBOX_ENV, chrome_sandbox_path)
+ env[CHROME_SANDBOX_ENV] = chrome_sandbox_path
+ else:
+ if verbose:
+ print 'Disabling sandbox. Setting environment variable:'
+ print ' CHROME_DEVEL_SANDBOX=""'
+ env['CHROME_DEVEL_SANDBOX'] = ''
+
+
+def fix_python_path(cmd):
+ """Returns the fixed command line to call the right python executable."""
+ out = cmd[:]
+ if out[0] == 'python':
+ out[0] = sys.executable
+ elif out[0].endswith('.py'):
+ out.insert(0, sys.executable)
+ return out
+
+
+def run_executable(cmd, env):
+ """Runs an executable with:
+ - environment variable CR_SOURCE_ROOT set to the root directory.
+ - environment variable LANGUAGE to en_US.UTF-8.
+ - environment variable CHROME_DEVEL_SANDBOX set if need
+ - Reuses sys.executable automatically.
+ """
+ # Many tests assume a English interface...
+ env['LANG'] = 'en_US.UTF-8'
+ # Used by base/base_paths_linux.cc as an override. Just make sure the default
+ # logic is used.
+ env.pop('CR_SOURCE_ROOT', None)
+ enable_sandbox_if_required(cmd, env)
+ # Ensure paths are correctly separated on windows.
+ cmd[0] = cmd[0].replace('/', os.path.sep)
+ cmd = fix_python_path(cmd)
+ try:
+ return subprocess.call(cmd, env=env)
+ except OSError:
+ print >> sys.stderr, 'Failed to start %s' % cmd
+ raise
+
+
+def main():
+ return run_executable(sys.argv[1:], os.environ.copy())
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/testing/xvfb.py b/testing/xvfb.py
new file mode 100755
index 0000000..ce53099
--- /dev/null
+++ b/testing/xvfb.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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.
+
+"""Runs the test with xvfb on linux. Runs the test normally on other platforms.
+
+For simplicity in gyp targets, this script just runs the test normal on
+non-linux platforms.
+"""
+
+import os
+import platform
+import signal
+import subprocess
+import sys
+
+import test_env
+
+
+def kill(pid):
+ """Kills a process and traps exception if the process doesn't exist anymore.
+ """
+ # If the process doesn't exist, it raises an exception that we can ignore.
+ try:
+ os.kill(pid, signal.SIGKILL)
+ except OSError:
+ pass
+
+
+def get_xvfb_path(server_dir):
+ """Figures out which X server to use."""
+ xvfb_path = os.path.join(server_dir, 'Xvfb.' + platform.architecture()[0])
+ if not os.path.exists(xvfb_path):
+ xvfb_path = os.path.join(server_dir, 'Xvfb')
+ if not os.path.exists(xvfb_path):
+ print >> sys.stderr, (
+ 'No Xvfb found in designated server path: %s' % server_dir)
+ raise Exception('No virtual server')
+ return xvfb_path
+
+
+def start_xvfb(xvfb_path, display):
+ """Starts a virtual X server that we run the tests in.
+
+ This makes it so we can run the tests even if we didn't start the tests from
+ an X session.
+
+ Args:
+ xvfb_path: Path to Xvfb.
+ """
+ cmd = [xvfb_path, display, '-screen', '0', '1024x768x24', '-ac',
+ '-nolisten', 'tcp']
+ try:
+ proc = subprocess.Popen(
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ except OSError:
+ print >> sys.stderr, 'Failed to run %s' % ' '.join(cmd)
+ return
+ return proc
+
+
+def wait_for_xvfb(xdisplaycheck, env):
+ """Waits for xvfb to be fully initialized by using xdisplaycheck."""
+ try:
+ _logs = subprocess.check_output(
+ [xdisplaycheck],
+ stderr=subprocess.STDOUT,
+ env=env)
+ except OSError:
+ print >> sys.stderr, 'Failed to load %s with cwd=%s' % (
+ xdisplaycheck, os.getcwd())
+ return False
+ except subprocess.CalledProcessError as e:
+ print >> sys.stderr, (
+ 'Xvfb failed to load properly (code %d) according to %s' %
+ (e.returncode, xdisplaycheck))
+ return False
+
+ return True
+
+
+def run_executable(cmd, build_dir, env):
+ """Runs an executable within a xvfb buffer on linux or normally on other
+ platforms.
+
+ Requires that both xvfb and openbox are installed on linux.
+
+ Detects recursion with an environment variable and do not create a recursive X
+ buffer if present.
+ """
+ # First look if we are inside a display.
+ if env.get('_CHROMIUM_INSIDE_XVFB') == '1':
+ # No need to recurse.
+ return test_env.run_executable(cmd, env)
+
+ pid = None
+ xvfb = 'Xvfb'
+ try:
+ if sys.platform == 'linux2':
+ # Defaults to X display 9.
+ display = ':9'
+ xvfb_proc = start_xvfb(xvfb, display)
+ if not xvfb_proc or not xvfb_proc.pid:
+ return 1
+ env['DISPLAY'] = display
+ if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env):
+ rc = xvfb_proc.poll()
+ if rc is None:
+ print 'Xvfb still running, stopping.'
+ xvfb_proc.terminate()
+ else:
+ print 'Xvfb exited, code %d' % rc
+
+ print 'Xvfb output:'
+ for l in xvfb_proc.communicate()[0].splitlines():
+ print '> %s' % l
+
+ return 3
+ # Inhibit recursion.
+ env['_CHROMIUM_INSIDE_XVFB'] = '1'
+ # Some ChromeOS tests need a window manager. Technically, it could be
+ # another script but that would be overkill.
+ try:
+ wm_cmd = ['openbox']
+ subprocess.Popen(
+ wm_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
+ except OSError:
+ print >> sys.stderr, 'Failed to run %s' % ' '.join(wm_cmd)
+ return 1
+ return test_env.run_executable(cmd, env)
+ finally:
+ if pid:
+ kill(pid)
+
+
+def main():
+ if len(sys.argv) < 3:
+ print >> sys.stderr, (
+ 'Usage: xvfb.py [path to build_dir] [command args...]')
+ return 2
+ return run_executable(sys.argv[2:], sys.argv[1], os.environ.copy())
+
+
+if __name__ == "__main__":
+ sys.exit(main())