| // 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 <stdio.h> |
| |
| #include "base/command_line.h" |
| #include "base/file_util.h" |
| #include "base/path_service.h" |
| #include "base/perftimer.h" |
| #include "base/string_util.h" |
| #include "chrome/app/chrome_dll_resource.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/libxml_utils.h" |
| #include "chrome/test/automation/autocomplete_edit_proxy.h" |
| #include "chrome/test/automation/automation_proxy.h" |
| #include "chrome/test/automation/browser_proxy.h" |
| #include "chrome/test/automation/window_proxy.h" |
| #include "chrome/test/ui/ui_test.h" |
| |
| const wchar_t kRunOmniboxTest[] = L"run_omnibox_test"; |
| |
| class OmniboxTest : public UITest { |
| public: |
| |
| double score_; |
| double max_score_; |
| |
| int query_count_; |
| int query_timeouts_; |
| int64 time_squared_; |
| int64 time_sum_; |
| int64 time_min_; |
| int64 time_max_; |
| |
| OmniboxTest() : UITest() { |
| show_window_ = true; |
| query_count_ = 0; |
| query_timeouts_ = 0; |
| score_ = 0; |
| max_score_ = 0; |
| time_squared_ = 0; |
| time_sum_ = 0; |
| time_min_ = 0; |
| time_max_ = 0; |
| } |
| |
| // Many times a user may enter something like "google.com". If |
| // http://www.google.com/ is suggested that should be considered a match. |
| // This could probably be accomplished with regex as well. Note that this |
| // method is called even when suggestion isn't a URL. |
| bool IsMatch(const std::wstring& input_test, const std::wstring& suggestion); |
| // Runs a query chain. This sends each proper prefix of the input to the |
| // omnibox and scores the autocompelte results returned. |
| void RunQueryChain(const std::wstring& input_text); |
| }; |
| |
| bool OmniboxTest::IsMatch(const std::wstring& input_text, |
| const std::wstring& suggestion) { |
| // This prefix list comes from the list used in history_url_provider.cc withiff |
| // the exception of "ftp." and "www.". |
| std::wstring prefixes[] = {L"", L"ftp://", L"http://", L"https://", |
| L"ftp.", L"www.", L"ftp://www.", L"ftp://ftp.", |
| L"http://www.", L"https://www."}; |
| std::wstring postfixes[] = {L"", L"/"}; |
| for (int i = 0; i < sizeof(prefixes) / sizeof(std::wstring); ++i) { |
| for (int j = 0; j < sizeof(postfixes) / sizeof(std::wstring); ++j) { |
| if (prefixes[i] + input_text + postfixes[j] == suggestion) |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void OmniboxTest::RunQueryChain(const std::wstring& input_text) { |
| // Get a handle on the omnibox and give it focus. |
| scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| scoped_ptr<WindowProxy> window( |
| automation()->GetWindowForBrowser(browser.get())); |
| scoped_ptr<AutocompleteEditProxy> autocomplete_edit( |
| automation()->GetAutocompleteEditForBrowser(browser.get())); |
| ASSERT_TRUE(browser->ApplyAccelerator(IDC_FOCUS_LOCATION)); |
| |
| // Try every proper prefix of input_text. There's no use trying |
| // input_text itself since the autocomplete results will always contain it. |
| for (size_t i = 1; i < input_text.size(); ++i) { |
| Matches matches; |
| |
| // We're only going to count the time elapsed waiting for autocomplete |
| // matches to be returned to us. |
| ASSERT_TRUE(autocomplete_edit->SetText(input_text.substr(0, i))); |
| PerfTimer timer; |
| if (autocomplete_edit->WaitForQuery(30000)) { |
| ASSERT_TRUE(autocomplete_edit->GetAutocompleteMatches(&matches)); |
| int64 time_elapsed = timer.Elapsed().InMilliseconds(); |
| |
| // Adjust statistic trackers. |
| if (query_count_ == 0) |
| time_min_ = time_max_ = time_elapsed; |
| ++query_count_; |
| time_squared_ += time_elapsed * time_elapsed; |
| time_sum_ += time_elapsed; |
| if (time_elapsed < time_min_) |
| time_min_ = time_elapsed; |
| if (time_elapsed > time_max_) |
| time_max_ = time_elapsed; |
| } else { |
| ++query_timeouts_; |
| } |
| wprintf(L"query: %d\n", query_count_); |
| |
| // Check if any suggestions match the input text. Stop if a match is |
| // found. |
| for (Matches::const_iterator j(matches.begin()); j != matches.end(); ++j) { |
| if (IsMatch(input_text, j->fill_into_edit)) { |
| score_ += i; |
| break; |
| } |
| } |
| max_score_ += i; |
| } |
| } |
| |
| // This test reads in the omnibox_tests.xml file and performs the tests |
| // within. The current format of xml is fairly simple. Nothing is currently |
| // done with the provider information. |
| // <omnibox_tests> |
| // Zero or more test elements. |
| // <test query='%query%'> |
| // Zero or more provider elements. |
| // <provider name='%expected_provider_name%'/> |
| // </test> |
| // </omnibox_tests> |
| |
| TEST_F(OmniboxTest, Measure) { |
| if (!CommandLine().HasSwitch(kRunOmniboxTest)) return; |
| |
| std::wstring omnibox_tests_path; |
| PathService::Get(chrome::DIR_TEST_DATA, &omnibox_tests_path); |
| file_util::AppendToPath(&omnibox_tests_path, L"omnibox_tests.xml"); |
| |
| XmlReader reader; |
| ASSERT_TRUE(reader.LoadFile(WideToASCII(omnibox_tests_path))); |
| while (reader.SkipToElement()) { |
| ASSERT_EQ("omnibox_tests", reader.NodeName()); |
| reader.Read(); |
| while (reader.SkipToElement()) { |
| ASSERT_EQ("test", reader.NodeName()); |
| std::string query; |
| std::vector<std::string> expected_providers; |
| ASSERT_TRUE(reader.NodeAttribute("query", &query)); |
| reader.Read(); |
| while (reader.SkipToElement()) { |
| ASSERT_EQ("provider", reader.NodeName()); |
| std::string provider; |
| ASSERT_TRUE(reader.NodeAttribute("provider", &provider)); |
| expected_providers.push_back(provider); |
| reader.Read(); |
| } |
| RunQueryChain(ASCIIToWide(query)); |
| reader.Read(); |
| } |
| reader.Read(); |
| } |
| |
| // Output results. |
| ASSERT_GT(query_count_, 0); |
| int64 mean = time_sum_ / query_count_; |
| wprintf(L"__om_query_count = %d\n", query_count_); |
| wprintf(L"__om_query_timeouts = %d\n", query_timeouts_); |
| wprintf(L"__om_time_per_query_avg = %d\n", mean); |
| // Use the equation stddev = sqrt(Sum(x_i^2)/N - mean^2). |
| wprintf(L"__om_time_per_query_stddev = %d\n", static_cast<int64>( |
| sqrt(1.0 * time_squared_ / query_count_ - mean * mean))); |
| wprintf(L"__om_time_per_query_max = %d\n", time_max_); |
| wprintf(L"__om_time_per_query_min = %d\n", time_min_); |
| wprintf(L"__om_score = %.4f\n", 100.0 * score_ / max_score_); |
| } |
| |