summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-25 07:40:28 +0000
committerukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-25 07:40:28 +0000
commitaa63fd306939e4edef29c8f490a4a23386cba034 (patch)
treef911b815e2a1fa3a53e7a236dc753d9d2fb5fd7a /chrome
parenta2dac37922dd4681bc636252adf06df14bda100a (diff)
downloadchromium_src-aa63fd306939e4edef29c8f490a4a23386cba034.zip
chromium_src-aa63fd306939e4edef29c8f490a4a23386cba034.tar.gz
chromium_src-aa63fd306939e4edef29c8f490a4a23386cba034.tar.bz2
Revert 86572 - Revert 86568 - Add initial framework for performance tests that measure frame rate.
Add the "blank page" test, which just scrolls a page with a very large body. The actual frame rate measurement is based on the webkitRequestAnimationFrame callback. The framework records how frequently that API generates a callback. If it generates a callback at 60 FPS, then we know nothing is slowing us down. This of course assumes that webkitRequestAnimationFrame is well implemented. The advantage of this test framework over one that directly reads a framerate from Chromium is that this one works outside of the test harness. You can just navigate your browser to the test file and run the test manually. R=brettw,nduca Review URL: http://codereview.chromium.org/7038052 TBR=darin@chromium.org BUG=none TEST=none TBR= git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86580 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/chrome_tests.gypi44
-rw-r--r--chrome/test/data/perf/frame_rate/blank/test.html4
-rw-r--r--chrome/test/data/perf/frame_rate/head.js100
-rw-r--r--chrome/test/perf/frame_rate/frame_rate_tests.cc110
-rw-r--r--chrome/test/ui/javascript_test_util.cc30
-rw-r--r--chrome/test/ui/ui_perf_test.h2
6 files changed, 280 insertions, 10 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 0c90bf8..61a7cc4 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2880,6 +2880,50 @@
],
},
{
+ 'target_name': 'performance_ui_tests',
+ 'type': 'executable',
+ 'msvs_guid': 'C3539D2F-B87A-4F9B-8220-1BB5F7119720',
+ 'dependencies': [
+ 'chrome',
+ 'chrome_resources',
+ 'chrome_strings',
+ 'debugger',
+ 'test_support_common',
+ 'test_support_ui',
+ '../base/base.gyp:base',
+ '../skia/skia.gyp:skia',
+ '../testing/gtest.gyp:gtest',
+ ],
+ 'sources': [
+ # TODO(darin): Move other UIPerfTests here.
+ 'test/perf/frame_rate/frame_rate_tests.cc',
+ ],
+ 'conditions': [
+ ['OS=="win" and buildtype=="Official"', {
+ 'configurations': {
+ 'Release': {
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'WholeProgramOptimization': 'false',
+ },
+ },
+ },
+ },
+ },],
+ ['OS=="linux"', {
+ 'dependencies': [
+ '../build/linux/system.gyp:gtk',
+ '../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck',
+ ],
+ }],
+ ['toolkit_views==1', {
+ 'dependencies': [
+ '../views/views.gyp:views',
+ ],
+ }],
+ ],
+ },
+ {
'target_name': 'tab_switching_test',
'type': 'executable',
'msvs_guid': 'A34770EA-A574-43E8-9327-F79C04770E98',
diff --git a/chrome/test/data/perf/frame_rate/blank/test.html b/chrome/test/data/perf/frame_rate/blank/test.html
new file mode 100644
index 0000000..e5d943c
--- /dev/null
+++ b/chrome/test/data/perf/frame_rate/blank/test.html
@@ -0,0 +1,4 @@
+<html>
+<head><script src="../head.js"></script></head>
+<body style="height: 50000px"></body>
+</html>
diff --git a/chrome/test/data/perf/frame_rate/head.js b/chrome/test/data/perf/frame_rate/head.js
new file mode 100644
index 0000000..6339f1e
--- /dev/null
+++ b/chrome/test/data/perf/frame_rate/head.js
@@ -0,0 +1,100 @@
+// Copyright (c) 2011 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.
+
+var __running = false;
+var __old_title = "";
+var __scroll_by = 300;
+var __raf;
+
+var __t_last;
+var __t_est;
+var __t_est_total;
+var __t_est_squared_total;
+var __t_count;
+
+function __init_stats() {
+ __t_last = undefined;
+ __t_est = undefined;
+ __t_est_total = 0;
+ __t_est_squared_total = 0;
+ __t_count = 0;
+}
+__init_stats();
+
+function __calc_results() {
+ var M = __t_est_total / __t_count;
+ var X = __t_est_squared_total / __t_count;
+ var V = X - M * M;
+ var S = Math.sqrt(V);
+
+ var R = new Object();
+ R.mean = 1000.0 / M;
+ R.sigma = R.mean - 1000.0 / (M + S);
+ return R;
+}
+
+function __scroll_down() {
+ var y = window.scrollY;
+ window.scrollBy(0, __scroll_by);
+ if (window.scrollY == y)
+ __stop();
+}
+
+function __update_fps() {
+ var t_now = new Date().getTime();
+ if (window.__t_last) {
+ var t_delta = t_now - __t_last;
+ if (window.__t_est) {
+ __t_est = (0.1 * __t_est) + (0.9 * t_delta); // low-pass filter
+ } else {
+ __t_est = t_delta;
+ }
+ var fps = 1000.0 / __t_est;
+ document.title = "FPS: " + (fps | 0);
+
+ __t_est_total += t_delta;
+ __t_est_squared_total += t_delta * t_delta;
+ __t_count++;
+ }
+ __t_last = t_now;
+}
+
+function __sched_update() {
+ if (!__raf) {
+ if ("webkitRequestAnimationFrame" in window)
+ __raf = webkitRequestAnimationFrame;
+ else if ("mozRequestAnimationFrame" in window)
+ __raf = mozRequestAnimationFrame;
+ }
+ __raf(function() {
+ if (!__running)
+ return;
+ __update_fps();
+ __scroll_down();
+ __sched_update();
+ });
+}
+
+function __start() {
+ if (__running)
+ return;
+ __old_title = document.title;
+ __running = true;
+ __sched_update();
+}
+
+function __stop() {
+ __running = false;
+ document.title = __old_title;
+}
+
+function __reset() {
+ __stop();
+ document.body.scrollTop = 0;
+ __init_stats();
+}
+
+function __force_compositor() {
+ document.body.style.webkitTransform = "translateZ(0)";
+}
diff --git a/chrome/test/perf/frame_rate/frame_rate_tests.cc b/chrome/test/perf/frame_rate/frame_rate_tests.cc
new file mode 100644
index 0000000..128a11d
--- /dev/null
+++ b/chrome/test/perf/frame_rate/frame_rate_tests.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2011 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 <map>
+
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_number_conversions.h"
+#include "base/test/test_timeouts.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/test/automation/tab_proxy.h"
+#include "chrome/test/ui/javascript_test_util.h"
+#include "chrome/test/ui/ui_perf_test.h"
+#include "net/base/net_util.h"
+
+namespace {
+
+class FrameRateTest : public UIPerfTest {
+ public:
+ FrameRateTest() {
+ show_window_ = true;
+ dom_automation_enabled_ = true;
+ }
+
+ virtual FilePath GetDataPath(const std::string& name) {
+ // Make sure the test data is checked out.
+ FilePath test_path;
+ PathService::Get(chrome::DIR_TEST_DATA, &test_path);
+ test_path = test_path.Append(FILE_PATH_LITERAL("perf"));
+ test_path = test_path.Append(FILE_PATH_LITERAL("frame_rate"));
+ test_path = test_path.AppendASCII(name);
+ return test_path;
+ }
+
+ void RunTest(const std::string& name, const std::string& suffix) {
+ FilePath test_path = GetDataPath(name);
+ ASSERT_TRUE(file_util::DirectoryExists(test_path))
+ << "Missing test directory: " << test_path.value();
+
+ test_path = test_path.Append(FILE_PATH_LITERAL("test.html"));
+
+ scoped_refptr<TabProxy> tab(GetActiveTab());
+ ASSERT_TRUE(tab.get());
+
+ ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
+ tab->NavigateToURL(net::FilePathToFileURL(test_path)));
+
+ // Start the test.
+ ASSERT_TRUE(tab->NavigateToURLAsync(GURL("javascript:__start();")));
+
+ // Block until the test completes.
+ ASSERT_TRUE(WaitUntilJavaScriptCondition(
+ tab, L"", L"window.domAutomationController.send(!__running);",
+ TestTimeouts::huge_test_timeout_ms()));
+
+ // Read out the results.
+ std::wstring json;
+ ASSERT_TRUE(tab->ExecuteAndExtractString(
+ L"",
+ L"window.domAutomationController.send("
+ L"JSON.stringify(__calc_results()));",
+ &json));
+
+ std::map<std::string, std::string> results;
+ ASSERT_TRUE(JsonDictionaryToMap(WideToUTF8(json), &results));
+
+ ASSERT_TRUE(results.find("mean") != results.end());
+ ASSERT_TRUE(results.find("sigma") != results.end());
+
+ std::string mean_and_error = results["mean"] + "," + results["sigma"];
+ PrintResultMeanAndError("fps" + suffix, "", "", mean_and_error,
+ "frames-per-second", false);
+ }
+};
+
+class FrameRateTest_Reference : public FrameRateTest {
+ public:
+ // Override the browser directory that is used by UITest::SetUp to cause it
+ // to use the reference build instead.
+ void SetUp() {
+ FilePath dir;
+ PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
+ dir = dir.AppendASCII("reference_build");
+#if defined(OS_WIN)
+ dir = dir.AppendASCII("chrome");
+#elif defined(OS_LINUX)
+ dir = dir.AppendASCII("chrome_linux");
+#elif defined(OS_MACOSX)
+ dir = dir.AppendASCII("chrome_mac");
+#endif
+ browser_directory_ = dir;
+ FrameRateTest::SetUp();
+ }
+};
+
+TEST_F(FrameRateTest, Blank) {
+ RunTest("blank", "");
+}
+
+// TODO(darin): Need to update the reference build to a version that supports
+// the webkitRequestAnimationFrame API.
+#if 0
+TEST_F(FrameRateTest_Reference, Blank) {
+ RunTest("blank", "_ref");
+}
+#endif
+
+} // namespace
diff --git a/chrome/test/ui/javascript_test_util.cc b/chrome/test/ui/javascript_test_util.cc
index acccdcb..87dcbb7 100644
--- a/chrome/test/ui/javascript_test_util.cc
+++ b/chrome/test/ui/javascript_test_util.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "content/common/json_value_serializer.h"
@@ -38,17 +39,28 @@ bool JsonDictionaryToMap(const std::string& json,
if (!succeeded)
continue;
- EXPECT_TRUE(value->IsType(Value::TYPE_STRING));
- if (value->IsType(Value::TYPE_STRING)) {
- const std::string& key(*it);
+ const std::string& key(*it);
+ std::string result;
- std::string result;
- succeeded = value->GetAsString(&result);
- EXPECT_TRUE(succeeded);
-
- if (succeeded)
- results->insert(std::make_pair(key, result));
+ switch (value->GetType()) {
+ case Value::TYPE_STRING:
+ succeeded = value->GetAsString(&result);
+ break;
+ case Value::TYPE_DOUBLE: {
+ double double_result;
+ succeeded = value->GetAsDouble(&double_result);
+ if (succeeded)
+ result = base::DoubleToString(double_result);
+ break;
+ }
+ default:
+ NOTREACHED() << "Value type not supported!";
+ return false;
}
+
+ EXPECT_TRUE(succeeded);
+ if (succeeded)
+ results->insert(std::make_pair(key, result));
}
return true;
diff --git a/chrome/test/ui/ui_perf_test.h b/chrome/test/ui/ui_perf_test.h
index cfc18df..8546dbe 100644
--- a/chrome/test/ui/ui_perf_test.h
+++ b/chrome/test/ui/ui_perf_test.h
@@ -45,7 +45,7 @@ class UIPerfTest : public UITest {
bool important);
// Like PrintResult(), but prints a (mean, standard deviation) result pair.
- // The |<values>| should be two comma-seaprated numbers, the mean and
+ // 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,