Commit c3cd91ff authored by Dominic Mazzoni's avatar Dominic Mazzoni Committed by Commit Bot

Add an initial perf test for automation.

Measures the amount of time spent unserializing changes to the
accessibility tree and sending automation events.

In order to scale reasonably well across different machines, this
time is compared to the amount of time spent in renderer
accessibility code, that way the test only fails if the
disparity is too large.

The test code is deliberately all one test for ease of review.
As we add more tests, a lot of the code could be broken up into
helpers.

Bug: none
Change-Id: I44a169a7c80d9ccea5cf70cb7450731a43638c7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2430304
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811534}
parent 85fcdf8c
......@@ -4,11 +4,13 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/path_service.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/trace_event_analyzer.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_apitest.h"
......@@ -21,6 +23,7 @@
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/tracing_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
......@@ -473,6 +476,73 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, AccessibilityFocus) {
<< message_;
}
IN_PROC_BROWSER_TEST_F(AutomationApiTest, TextareaAppendPerf) {
StartEmbeddedTestServer();
{
base::RunLoop wait_for_tracing;
content::TracingController::GetInstance()->StartTracing(
base::trace_event::TraceConfig(
R"({"included_categories": ["accessibility"])"),
wait_for_tracing.QuitClosure());
wait_for_tracing.Run();
}
ASSERT_TRUE(
RunExtensionSubtest("automation/tests/tabs", "textarea_append_perf.html"))
<< message_;
std::string trace_output;
{
base::RunLoop wait_for_tracing;
content::TracingController::GetInstance()->StopTracing(
content::TracingController::CreateStringEndpoint(base::BindOnce(
[](base::OnceClosure quit_closure, std::string* output,
std::unique_ptr<std::string> trace_str) {
*output = *trace_str;
std::move(quit_closure).Run();
},
wait_for_tracing.QuitClosure(), &trace_output)));
wait_for_tracing.Run();
}
base::Optional<base::Value> trace_data = base::JSONReader::Read(trace_output);
ASSERT_TRUE(trace_data);
const base::Value* trace_events = trace_data->FindListKey("traceEvents");
ASSERT_TRUE(trace_events && trace_events->is_list());
int renderer_total_dur = 0;
int automation_total_dur = 0;
for (const base::Value& event : trace_events->GetList()) {
const std::string* cat = event.FindStringKey("cat");
if (!cat || *cat != "accessibility")
continue;
const std::string* name = event.FindStringKey("name");
if (!name)
continue;
base::Optional<int> dur = event.FindIntKey("dur");
if (!dur)
continue;
if (*name == "AutomationAXTreeWrapper::OnAccessibilityEvents")
automation_total_dur += *dur;
else if (*name == "RenderAccessibilityImpl::SendPendingAccessibilityEvents")
renderer_total_dur += *dur;
}
ASSERT_GT(automation_total_dur, 0);
ASSERT_GT(renderer_total_dur, 0);
LOG(INFO) << "Total duration in automation: " << automation_total_dur;
LOG(INFO) << "Total duration in renderer: " << renderer_total_dur;
// Assert that the time spent in automation isn't more than 2x
// the time spent in the renderer code.
ASSERT_LT(automation_total_dur, renderer_total_dur * 2);
}
#endif // defined(OS_CHROMEOS)
} // namespace extensions
<!--
* Copyright 2020 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.
-->
<html>
<head>
<title>Automation Tests - TextArea Append Perf</title>
</head>
<body>
<button>Go</button>
<textarea id="testElement" spellcheck=false style="height:90vh"></textarea>
<a id="done" href="#">Done</a>
<script>
let button = document.body.querySelector('button');
button.addEventListener('click', () => {
// Fill the textarea with 10 lines of random numbers,
// 10 times, and then focus the 'done' link.
let testElement = document.getElementById('testElement');
function go(iteration) {
if (iteration == 10) {
document.getElementById('done').focus();
} else {
testElement.textContent += new Array(100).fill(0).map(
(_, i) => Math.floor(100*Math.random())).join('\n');
setTimeout(() => {
go(iteration + 1);
}, 0);
}
}
go(0);
});
</script>
</body>
</html>
<!--
* Copyright 2020 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.
-->
<script src="common.js"></script>
<script src="textarea_append_perf.js"></script>
// Copyright 2020 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 allTests = [
function testTextareaAppend() {
let runButton = rootNode.find({ role: 'button'});
assertEq('button', runButton.role);
let doneLink = rootNode.find({ role: 'link'});
assertEq('link', doneLink.role);
rootNode.addEventListener('childrenChanged', (evt) => {
});
doneLink.addEventListener('focus', () => {
chrome.test.succeed();
});
runButton.doDefault();
}
];
setUpAndRunTests(allTests, 'textarea_append.html');
......@@ -44,6 +44,9 @@ AutomationAXTreeWrapper* AutomationAXTreeWrapper::GetParentOfTreeId(
bool AutomationAXTreeWrapper::OnAccessibilityEvents(
const ExtensionMsg_AccessibilityEventBundleParams& event_bundle,
bool is_active_profile) {
TRACE_EVENT0("accessibility",
"AutomationAXTreeWrapper::OnAccessibilityEvents");
base::Optional<gfx::Rect> previous_accessibility_focused_global_bounds =
owner_->GetAccessibilityFocusedLocation();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment