OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This program generates a user profile and history by randomly generating | 5 // This program generates a user profile and history by randomly generating |
6 // data and feeding it to the history service. | 6 // data and feeding it to the history service. |
7 | 7 |
8 #include "chrome/tools/profiles/thumbnail-inl.h" | 8 #include "chrome/tools/profiles/thumbnail-inl.h" |
9 | 9 |
10 #include "base/at_exit.h" | 10 #include "base/at_exit.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
14 #include "base/i18n/icu_util.h" | 14 #include "base/i18n/icu_util.h" |
| 15 #include "base/logging.h" |
15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
16 #include "base/path_service.h" | 17 #include "base/path_service.h" |
17 #include "base/process_util.h" | 18 #include "base/process_util.h" |
18 #include "base/string_number_conversions.h" | 19 #include "base/string_number_conversions.h" |
19 #include "base/time.h" | 20 #include "base/time.h" |
20 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" |
21 #include "chrome/browser/history/history.h" | 22 #include "chrome/browser/history/history.h" |
22 #include "chrome/browser/history/history_service_factory.h" | 23 #include "chrome/browser/history/history_service_factory.h" |
23 #include "chrome/browser/history/top_sites.h" | 24 #include "chrome/browser/history/top_sites.h" |
24 #include "chrome/common/chrome_paths.h" | 25 #include "chrome/common/chrome_paths.h" |
25 #include "chrome/common/thumbnail_score.h" | 26 #include "chrome/common/thumbnail_score.h" |
| 27 #include "chrome/test/base/testing_browser_process.h" |
26 #include "chrome/test/base/testing_profile.h" | 28 #include "chrome/test/base/testing_profile.h" |
27 #include "content/browser/browser_thread_impl.h" | 29 #include "content/browser/browser_thread_impl.h" |
28 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
30 #include "third_party/skia/include/core/SkBitmap.h" | 32 #include "third_party/skia/include/core/SkBitmap.h" |
31 #include "ui/base/resource/resource_bundle.h" | 33 #include "ui/base/resource/resource_bundle.h" |
32 #include "ui/base/ui_base_paths.h" | 34 #include "ui/base/ui_base_paths.h" |
33 #include "ui/gfx/codec/jpeg_codec.h" | 35 #include "ui/gfx/codec/jpeg_codec.h" |
34 | 36 |
| 37 #if defined(TOOLKIT_GTK) |
| 38 #include <gtk/gtk.h> |
| 39 #endif |
| 40 |
35 using base::Time; | 41 using base::Time; |
36 using content::BrowserThread; | 42 using content::BrowserThread; |
37 | 43 |
38 // Addition types data can be generated for. By default only urls/visits are | 44 // Addition types data can be generated for. By default only urls/visits are |
39 // added. | 45 // added. |
40 enum Types { | 46 enum Types { |
41 TOP_SITES = 1 << 0, | 47 TOP_SITES = 1 << 0, |
42 FULL_TEXT = 1 << 1 | 48 FULL_TEXT = 1 << 1 |
43 }; | 49 }; |
44 | 50 |
| 51 // RAII for initializing and shutting down the TestBrowserProcess |
| 52 class InitBrowserProcess { |
| 53 public: |
| 54 InitBrowserProcess() { |
| 55 DCHECK(!g_browser_process); |
| 56 g_browser_process = new TestingBrowserProcess; |
| 57 } |
| 58 |
| 59 ~InitBrowserProcess() { |
| 60 DCHECK(g_browser_process); |
| 61 delete g_browser_process; |
| 62 g_browser_process = NULL; |
| 63 } |
| 64 }; |
| 65 |
45 // Probabilities of different word lengths, as measured from Darin's profile. | 66 // Probabilities of different word lengths, as measured from Darin's profile. |
46 // kWordLengthProbabilities[n-1] = P(word of length n) | 67 // kWordLengthProbabilities[n-1] = P(word of length n) |
47 const float kWordLengthProbabilities[] = { 0.069f, 0.132f, 0.199f, | 68 const float kWordLengthProbabilities[] = { 0.069f, 0.132f, 0.199f, |
48 0.137f, 0.088f, 0.115f, 0.081f, 0.055f, 0.034f, 0.021f, 0.019f, 0.018f, | 69 0.137f, 0.088f, 0.115f, 0.081f, 0.055f, 0.034f, 0.021f, 0.019f, 0.018f, |
49 0.007f, 0.007f, 0.005f, 0.004f, 0.003f, 0.003f, 0.003f }; | 70 0.007f, 0.007f, 0.005f, 0.004f, 0.003f, 0.003f, 0.003f }; |
50 | 71 |
51 // Return a float uniformly in [0,1]. | 72 // Return a float uniformly in [0,1]. |
52 // Useful for making probabilistic decisions. | 73 // Useful for making probabilistic decisions. |
53 float RandomFloat() { | 74 float RandomFloat() { |
54 return rand() / static_cast<float>(RAND_MAX); | 75 return rand() / static_cast<float>(RAND_MAX); |
55 } | 76 } |
56 | 77 |
57 // Return an integer uniformly in [min,max). | 78 // Return an integer uniformly in [min,max). |
58 int RandomInt(int min, int max) { | 79 int RandomInt(int min, int max) { |
59 return min + (rand() % (max-min)); | 80 return min + (rand() % (max-min)); |
60 } | 81 } |
61 | 82 |
62 // Return a string of |count| lowercase random characters. | 83 // Return a string of |count| lowercase random characters. |
63 std::wstring RandomChars(int count) { | 84 string16 RandomChars(int count) { |
64 std::wstring str; | 85 string16 str; |
65 for (int i = 0; i < count; ++i) | 86 for (int i = 0; i < count; ++i) |
66 str += L'a' + rand() % 26; | 87 str += L'a' + rand() % 26; |
67 return str; | 88 return str; |
68 } | 89 } |
69 | 90 |
70 std::wstring RandomWord() { | 91 string16 RandomWord() { |
71 // TODO(evanm): should we instead use the markov chain based | 92 // TODO(evanm): should we instead use the markov chain based |
72 // version of this that I already wrote? | 93 // version of this that I already wrote? |
73 | 94 |
74 // Sample a word length from kWordLengthProbabilities. | 95 // Sample a word length from kWordLengthProbabilities. |
75 float sample = RandomFloat(); | 96 float sample = RandomFloat(); |
76 int i; | 97 size_t i; |
77 for (i = 0; i < arraysize(kWordLengthProbabilities); ++i) { | 98 for (i = 0; i < arraysize(kWordLengthProbabilities); ++i) { |
78 sample -= kWordLengthProbabilities[i]; | 99 sample -= kWordLengthProbabilities[i]; |
79 if (sample < 0) break; | 100 if (sample < 0) break; |
80 } | 101 } |
81 const int word_length = i + 1; | 102 const int word_length = i + 1; |
82 return RandomChars(word_length); | 103 return RandomChars(word_length); |
83 } | 104 } |
84 | 105 |
85 // Return a string of |count| random words. | 106 // Return a string of |count| random words. |
86 std::wstring RandomWords(int count) { | 107 string16 RandomWords(int count) { |
87 std::wstring str; | 108 string16 str; |
88 for (int i = 0; i < count; ++i) { | 109 for (int i = 0; i < count; ++i) { |
89 if (!str.empty()) | 110 if (!str.empty()) |
90 str += L' '; | 111 str += L' '; |
91 str += RandomWord(); | 112 str += RandomWord(); |
92 } | 113 } |
93 return str; | 114 return str; |
94 } | 115 } |
95 | 116 |
96 // Return a random URL-looking string. | 117 // Return a random URL-looking string. |
97 GURL ConstructRandomURL() { | 118 GURL ConstructRandomURL() { |
98 return GURL(std::wstring(L"http://") + RandomChars(3) + L".com/" + | 119 return GURL(ASCIIToUTF16("http://") + RandomChars(3) + ASCIIToUTF16(".com/") + |
99 RandomChars(RandomInt(5, 20))); | 120 RandomChars(RandomInt(5, 20))); |
100 } | 121 } |
101 | 122 |
102 // Return a random page title-looking string. | 123 // Return a random page title-looking string. |
103 std::wstring ConstructRandomTitle() { | 124 string16 ConstructRandomTitle() { |
104 return RandomWords(RandomInt(3, 15)); | 125 return RandomWords(RandomInt(3, 15)); |
105 } | 126 } |
106 | 127 |
107 // Return a random string that could function as page contents. | 128 // Return a random string that could function as page contents. |
108 std::wstring ConstructRandomPage() { | 129 string16 ConstructRandomPage() { |
109 return RandomWords(RandomInt(10, 4000)); | 130 return RandomWords(RandomInt(10, 4000)); |
110 } | 131 } |
111 | 132 |
112 // Insert a batch of |batch_size| URLs, starting at pageid |page_id|. | 133 // Insert a batch of |batch_size| URLs, starting at pageid |page_id|. |
113 void InsertURLBatch(Profile* profile, | 134 void InsertURLBatch(Profile* profile, |
114 int page_id, | 135 int page_id, |
115 int batch_size, | 136 int batch_size, |
116 int types) { | 137 int types) { |
117 HistoryService* history_service = | 138 HistoryService* history_service = |
118 HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS); | 139 HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 top_sites->SetPageThumbnail(url, image, score); | 209 top_sites->SetPageThumbnail(url, image, score); |
189 } | 210 } |
190 | 211 |
191 previous_url = url; | 212 previous_url = url; |
192 | 213 |
193 if (revisit_urls.empty() || RandomFloat() < kRevisitableURLProbability) | 214 if (revisit_urls.empty() || RandomFloat() < kRevisitableURLProbability) |
194 revisit_urls.push_back(url); | 215 revisit_urls.push_back(url); |
195 } | 216 } |
196 } | 217 } |
197 | 218 |
198 int main(int argc, const char* argv[]) { | 219 int main(int argc, char* argv[]) { |
199 CommandLine::Init(argc, argv); | 220 CommandLine::Init(argc, argv); |
200 base::EnableTerminationOnHeapCorruption(); | 221 base::EnableTerminationOnHeapCorruption(); |
201 base::AtExitManager exit_manager; | 222 base::AtExitManager exit_manager; |
202 CommandLine* cl = CommandLine::ForCurrentProcess(); | 223 CommandLine* cl = CommandLine::ForCurrentProcess(); |
203 | 224 |
204 int types = 0; | 225 int types = 0; |
205 if (cl->HasSwitch("top-sites")) | 226 if (cl->HasSwitch("top-sites")) |
206 types |= TOP_SITES; | 227 types |= TOP_SITES; |
207 if (cl->HasSwitch("full-text")) | 228 if (cl->HasSwitch("full-text")) |
208 types |= FULL_TEXT; | 229 types |= FULL_TEXT; |
209 | 230 |
210 // We require two arguments: urlcount and profiledir. | 231 // We require two arguments: urlcount and profiledir. |
211 const CommandLine::StringVector& args = cl->GetArgs(); | 232 const CommandLine::StringVector& args = cl->GetArgs(); |
212 if (args.size() < 2) { | 233 if (args.size() < 2) { |
213 printf("usage: %s [--top-sites] [--full-text] <urlcount> " | 234 printf("usage: %s [--top-sites] [--full-text] <urlcount> " |
214 "<profiledir>\n", argv[0]); | 235 "<profiledir>\n", argv[0]); |
215 printf("\n --top-sites Generate thumbnails\n"); | 236 printf("\n --top-sites Generate thumbnails\n"); |
216 printf("\n --full-text Generate full text index\n"); | 237 printf("\n --full-text Generate full text index\n"); |
217 return -1; | 238 return -1; |
218 } | 239 } |
219 | 240 |
220 int url_count = 0; | 241 int url_count = 0; |
221 base::StringToInt(WideToUTF8(args[0]), &url_count); | 242 base::StringToInt(args[0], &url_count); |
222 FilePath dst_dir(args[1]); | 243 FilePath dst_dir(args[1]); |
223 if (!dst_dir.IsAbsolute()) { | 244 if (!dst_dir.IsAbsolute()) { |
224 FilePath current_dir; | 245 FilePath current_dir; |
225 file_util::GetCurrentDirectory(¤t_dir); | 246 file_util::GetCurrentDirectory(¤t_dir); |
226 dst_dir = current_dir.Append(dst_dir); | 247 dst_dir = current_dir.Append(dst_dir); |
227 } | 248 } |
228 if (!file_util::CreateDirectory(dst_dir)) { | 249 if (!file_util::CreateDirectory(dst_dir)) { |
229 printf("Unable to create directory %ls: %d\n", | 250 PLOG(ERROR) << "Unable to create directory " << dst_dir.value().c_str(); |
230 dst_dir.value().c_str(), | |
231 ::GetLastError()); | |
232 } | 251 } |
233 | 252 |
234 icu_util::Initialize(); | 253 icu_util::Initialize(); |
| 254 // Copied from base/test/test_suite.cc. |
| 255 #if defined(TOOLKIT_GTK) |
| 256 gtk_init_check(&argc, &argv); |
| 257 #endif |
235 | 258 |
| 259 InitBrowserProcess initialize_browser_process; |
236 chrome::RegisterPathProvider(); | 260 chrome::RegisterPathProvider(); |
237 ui::RegisterPathProvider(); | 261 ui::RegisterPathProvider(); |
238 ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); | |
239 scoped_ptr<content::NotificationService> notification_service( | |
240 content::NotificationService::Create()); | |
241 MessageLoopForUI message_loop; | 262 MessageLoopForUI message_loop; |
242 content::BrowserThreadImpl ui_thread(BrowserThread::UI, &message_loop); | 263 content::BrowserThreadImpl ui_thread(BrowserThread::UI, &message_loop); |
243 content::BrowserThreadImpl db_thread(BrowserThread::DB, &message_loop); | 264 content::BrowserThreadImpl db_thread(BrowserThread::DB, &message_loop); |
| 265 ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); |
244 TestingProfile profile; | 266 TestingProfile profile; |
245 profile.CreateHistoryService(false, false); | 267 profile.CreateHistoryService(false, false); |
246 if (types & TOP_SITES) { | 268 if (types & TOP_SITES) { |
247 profile.CreateTopSites(); | 269 profile.CreateTopSites(); |
248 profile.BlockUntilTopSitesLoaded(); | 270 profile.BlockUntilTopSitesLoaded(); |
249 } | 271 } |
250 | 272 |
251 srand(static_cast<unsigned int>(Time::Now().ToInternalValue())); | 273 srand(static_cast<unsigned int>(Time::Now().ToInternalValue())); |
252 | 274 |
253 // The maximum number of URLs to insert into history in one batch. | 275 // The maximum number of URLs to insert into history in one batch. |
(...skipping 13 matching lines...) Expand all Loading... |
267 profile.DestroyHistoryService(); | 289 profile.DestroyHistoryService(); |
268 | 290 |
269 message_loop.RunUntilIdle(); | 291 message_loop.RunUntilIdle(); |
270 | 292 |
271 file_util::FileEnumerator file_iterator(profile.GetPath(), false, | 293 file_util::FileEnumerator file_iterator(profile.GetPath(), false, |
272 file_util::FileEnumerator::FILES); | 294 file_util::FileEnumerator::FILES); |
273 FilePath path = file_iterator.Next(); | 295 FilePath path = file_iterator.Next(); |
274 while (!path.empty()) { | 296 while (!path.empty()) { |
275 FilePath dst_file = dst_dir.Append(path.BaseName()); | 297 FilePath dst_file = dst_dir.Append(path.BaseName()); |
276 file_util::Delete(dst_file, false); | 298 file_util::Delete(dst_file, false); |
277 printf("Copying file %ls to %ls\n", path.value().c_str(), | 299 printf("Copying file %" PRFilePath " to " |
| 300 "%" PRFilePath "\n", path.value().c_str(), |
278 dst_file.value().c_str()); | 301 dst_file.value().c_str()); |
279 if (!file_util::CopyFile(path, dst_file)) { | 302 if (!file_util::CopyFile(path, dst_file)) { |
280 printf("Copying file failed: %d\n", ::GetLastError()); | 303 PLOG(ERROR) << "Copying file failed"; |
281 return -1; | 304 return -1; |
282 } | 305 } |
283 path = file_iterator.Next(); | 306 path = file_iterator.Next(); |
284 } | 307 } |
285 | 308 |
286 return 0; | 309 return 0; |
287 } | 310 } |
OLD | NEW |