| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <math.h> | |
| 6 #include <stdio.h> | |
| 7 | |
| 8 #include "base/command_line.h" | |
| 9 #include "base/file_util.h" | |
| 10 #include "base/path_service.h" | |
| 11 #include "base/perftimer.h" | |
| 12 #include "base/string_util.h" | |
| 13 #include "base/test/test_timeouts.h" | |
| 14 #include "base/utf_string_conversions.h" | |
| 15 #include "chrome/app/chrome_command_ids.h" | |
| 16 #include "chrome/common/chrome_paths.h" | |
| 17 #include "chrome/common/libxml_utils.h" | |
| 18 #include "chrome/test/automation/autocomplete_edit_proxy.h" | |
| 19 #include "chrome/test/automation/automation_proxy.h" | |
| 20 #include "chrome/test/automation/browser_proxy.h" | |
| 21 #include "chrome/test/automation/window_proxy.h" | |
| 22 #include "chrome/test/ui/ui_test.h" | |
| 23 | |
| 24 const char kRunOmniboxTest[] = "run_omnibox_test"; | |
| 25 | |
| 26 class OmniboxTest : public UITest { | |
| 27 public: | |
| 28 | |
| 29 double score_; | |
| 30 double max_score_; | |
| 31 | |
| 32 int query_count_; | |
| 33 int query_timeouts_; | |
| 34 int64 time_squared_; | |
| 35 int64 time_sum_; | |
| 36 int64 time_min_; | |
| 37 int64 time_max_; | |
| 38 | |
| 39 OmniboxTest() : UITest() { | |
| 40 show_window_ = true; | |
| 41 query_count_ = 0; | |
| 42 query_timeouts_ = 0; | |
| 43 score_ = 0; | |
| 44 max_score_ = 0; | |
| 45 time_squared_ = 0; | |
| 46 time_sum_ = 0; | |
| 47 time_min_ = 0; | |
| 48 time_max_ = 0; | |
| 49 } | |
| 50 | |
| 51 // Many times a user may enter something like "google.com". If | |
| 52 // http://www.google.com/ is suggested that should be considered a match. | |
| 53 // This could probably be accomplished with regex as well. Note that this | |
| 54 // method is called even when suggestion isn't a URL. | |
| 55 bool IsMatch(const string16& input_test, const string16& suggestion); | |
| 56 // Runs a query chain. This sends each proper prefix of the input to the | |
| 57 // omnibox and scores the autocompelte results returned. | |
| 58 void RunQueryChain(const string16& input_text); | |
| 59 }; | |
| 60 | |
| 61 bool OmniboxTest::IsMatch(const string16& input_text, | |
| 62 const string16& suggestion) { | |
| 63 // This prefix list comes from the list used in history_url_provider.cc | |
| 64 // with the exception of "ftp." and "www.". | |
| 65 string16 prefixes[] = {ASCIIToUTF16(""), ASCIIToUTF16("ftp://"), | |
| 66 ASCIIToUTF16("http://"), ASCIIToUTF16("https://"), ASCIIToUTF16("ftp."), | |
| 67 ASCIIToUTF16("www."), ASCIIToUTF16("ftp://www."), | |
| 68 ASCIIToUTF16("ftp://ftp."), ASCIIToUTF16("http://www."), | |
| 69 ASCIIToUTF16("https://www.")}; | |
| 70 string16 postfixes[] = {ASCIIToUTF16(""), ASCIIToUTF16("/")}; | |
| 71 for (size_t i = 0; i < arraysize(prefixes); ++i) { | |
| 72 for (size_t j = 0; j < arraysize(postfixes); ++j) { | |
| 73 if (prefixes[i] + input_text + postfixes[j] == suggestion) | |
| 74 return true; | |
| 75 } | |
| 76 } | |
| 77 return false; | |
| 78 } | |
| 79 | |
| 80 void OmniboxTest::RunQueryChain(const string16& input_text) { | |
| 81 // Get a handle on the omnibox and give it focus. | |
| 82 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | |
| 83 ASSERT_TRUE(browser.get()); | |
| 84 scoped_refptr<WindowProxy> window(browser->GetWindow()); | |
| 85 ASSERT_TRUE(window.get()); | |
| 86 scoped_refptr<AutocompleteEditProxy> autocomplete_edit( | |
| 87 browser->GetAutocompleteEdit()); | |
| 88 ASSERT_TRUE(browser->ApplyAccelerator(IDC_FOCUS_LOCATION)); | |
| 89 | |
| 90 // Try every proper prefix of input_text. There's no use trying | |
| 91 // input_text itself since the autocomplete results will always contain it. | |
| 92 for (size_t i = 1; i < input_text.size(); ++i) { | |
| 93 Matches matches; | |
| 94 | |
| 95 // We're only going to count the time elapsed waiting for autocomplete | |
| 96 // matches to be returned to us. | |
| 97 ASSERT_TRUE(autocomplete_edit->SetText(input_text.substr(0, i))); | |
| 98 PerfTimer timer; | |
| 99 if (autocomplete_edit->WaitForQuery( | |
| 100 TestTimeouts::action_max_timeout_ms())) { | |
| 101 ASSERT_TRUE(autocomplete_edit->GetAutocompleteMatches(&matches)); | |
| 102 int64 time_elapsed = timer.Elapsed().InMilliseconds(); | |
| 103 | |
| 104 // Adjust statistic trackers. | |
| 105 if (query_count_ == 0) | |
| 106 time_min_ = time_max_ = time_elapsed; | |
| 107 ++query_count_; | |
| 108 time_squared_ += time_elapsed * time_elapsed; | |
| 109 time_sum_ += time_elapsed; | |
| 110 if (time_elapsed < time_min_) | |
| 111 time_min_ = time_elapsed; | |
| 112 if (time_elapsed > time_max_) | |
| 113 time_max_ = time_elapsed; | |
| 114 } else { | |
| 115 ++query_timeouts_; | |
| 116 } | |
| 117 wprintf(L"query: %d\n", query_count_); | |
| 118 | |
| 119 // Check if any suggestions match the input text. Stop if a match is | |
| 120 // found. | |
| 121 for (Matches::const_iterator j(matches.begin()); j != matches.end(); ++j) { | |
| 122 if (IsMatch(input_text, j->fill_into_edit)) { | |
| 123 score_ += i; | |
| 124 break; | |
| 125 } | |
| 126 } | |
| 127 max_score_ += i; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 // This test reads in the omnibox_tests.xml file and performs the tests | |
| 132 // within. The current format of xml is fairly simple. Nothing is currently | |
| 133 // done with the provider information. | |
| 134 // <omnibox_tests> | |
| 135 // Zero or more test elements. | |
| 136 // <test query='%query%'> | |
| 137 // Zero or more provider elements. | |
| 138 // <provider name='%expected_provider_name%'/> | |
| 139 // </test> | |
| 140 // </omnibox_tests> | |
| 141 | |
| 142 TEST_F(OmniboxTest, Measure) { | |
| 143 if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunOmniboxTest)) | |
| 144 return; | |
| 145 | |
| 146 FilePath omnibox_tests_path; | |
| 147 PathService::Get(chrome::DIR_TEST_DATA, &omnibox_tests_path); | |
| 148 omnibox_tests_path = omnibox_tests_path.AppendASCII("omnibox_tests.xml"); | |
| 149 | |
| 150 XmlReader reader; | |
| 151 ASSERT_TRUE(reader.LoadFile(omnibox_tests_path)); | |
| 152 while (reader.SkipToElement()) { | |
| 153 ASSERT_EQ("omnibox_tests", reader.NodeName()); | |
| 154 reader.Read(); | |
| 155 while (reader.SkipToElement()) { | |
| 156 ASSERT_EQ("test", reader.NodeName()); | |
| 157 std::string query; | |
| 158 std::vector<std::string> expected_providers; | |
| 159 ASSERT_TRUE(reader.NodeAttribute("query", &query)); | |
| 160 reader.Read(); | |
| 161 while (reader.SkipToElement()) { | |
| 162 ASSERT_EQ("provider", reader.NodeName()); | |
| 163 std::string provider; | |
| 164 ASSERT_TRUE(reader.NodeAttribute("provider", &provider)); | |
| 165 expected_providers.push_back(provider); | |
| 166 reader.Read(); | |
| 167 } | |
| 168 RunQueryChain(ASCIIToUTF16(query)); | |
| 169 reader.Read(); | |
| 170 } | |
| 171 reader.Read(); | |
| 172 } | |
| 173 | |
| 174 // Output results. | |
| 175 ASSERT_GT(query_count_, 0); | |
| 176 int64 mean = time_sum_ / query_count_; | |
| 177 wprintf(L"__om_query_count = %d\n", query_count_); | |
| 178 wprintf(L"__om_query_timeouts = %d\n", query_timeouts_); | |
| 179 wprintf(L"__om_time_per_query_avg = %d\n", mean); | |
| 180 // Use the equation stddev = sqrt(Sum(x_i^2)/N - mean^2). | |
| 181 wprintf(L"__om_time_per_query_stddev = %d\n", static_cast<int64>( | |
| 182 sqrt(1.0 * time_squared_ / query_count_ - mean * mean))); | |
| 183 wprintf(L"__om_time_per_query_max = %d\n", time_max_); | |
| 184 wprintf(L"__om_time_per_query_min = %d\n", time_min_); | |
| 185 wprintf(L"__om_score = %.4f\n", 100.0 * score_ / max_score_); | |
| 186 } | |
| OLD | NEW |