1// Copyright 2013 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 "base/metrics/histogram.h"
6#include "base/strings/stringprintf.h"
7#include "chrome/browser/extensions/activity_log/uma_policy.h"
8#include "chrome/browser/extensions/extension_apitest.h"
9#include "chrome/browser/extensions/extension_browsertest.h"
10#include "chrome/browser/extensions/extension_service.h"
11#include "chrome/browser/extensions/test_extension_dir.h"
12#include "chrome/browser/ui/browser_window.h"
13#include "chrome/test/base/ui_test_utils.h"
14#include "extensions/common/manifest_constants.h"
15#include "net/dns/mock_host_resolver.h"
16
17using extensions::UmaPolicy;
18
19const char* kGooglePrefix = "ExtensionActivity.Google";
20const char* kNonGooglePrefix = "ExtensionActivity";
21
22// These tests need to ensure that all of the extension JavaScript completes
23// before the histograms are checked. To accomplish this, the test relies on
24// some JavaScript in chrome/test/data/extensions/api_test/uma_policy/:
25// * When the test navigates to opener.com, opener.js will use window.open() to
26//   pop open a new window with the appropriate URL for the test case. This
27//   ensures that the testing framework never reuses a window that's still
28//   running a previous test case.
29// * The test extension code in content_script.js tells background.js when it's
30//   done. When it's finished, background.js closes the blocker.com window. So
31//   blocker.com will remain open (and block) until the tests complete.
32class ActivityLogUmaPolicyTest : public ExtensionApiTest {
33};
34
35std::string ConcatNames(const char* prefix, int status_num) {
36  return base::StringPrintf(
37      "%s.%s",
38      prefix,
39      extensions::UmaPolicy::GetHistogramName(
40          static_cast<extensions::UmaPolicy::PageStatus>(status_num)));
41}
42
43// TODO(felt): These are disabled due to crbug.com/294500, since they fail
44// due to a blink bug. The fix went in to Blink on Thursday and should roll
45// on Monday 9/23.
46// These are all sequential navigations, so they should each be logged
47// independently.
48IN_PROC_BROWSER_TEST_F(ActivityLogUmaPolicyTest, DISABLED_SequentialNavs) {
49  host_resolver()->AddRule("*", "127.0.0.1");
50  StartEmbeddedTestServer();
51
52  const extensions::Extension* ext =
53      LoadExtension(test_data_dir_.AppendASCII("uma_policy"));
54  ASSERT_TRUE(ext);
55
56  ui_test_utils::NavigateToURLWithDisposition(
57        browser(), GURL("http://www.opener.com/#google"), NEW_WINDOW,
58        ui_test_utils::BROWSER_TEST_NONE);
59  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
60      browser(), GURL("http://www.blocker.com"), 2);
61  ui_test_utils::NavigateToURLWithDisposition(
62        browser(), GURL("http://www.opener.com/#google?q=a"), NEW_WINDOW,
63        ui_test_utils::BROWSER_TEST_NONE);
64  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
65      browser(), GURL("http://www.blocker.com"), 2);
66  ui_test_utils::NavigateToURLWithDisposition(
67        browser(), GURL("http://www.opener.com/#google?q=b"), NEW_WINDOW,
68        ui_test_utils::BROWSER_TEST_NONE);
69  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
70      browser(), GURL("http://www.blocker.com"), 2);
71  ui_test_utils::NavigateToURLWithDisposition(
72        browser(), GURL("http://www.opener.com/#cnn?q=a"), NEW_WINDOW,
73        ui_test_utils::BROWSER_TEST_NONE);
74  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
75      browser(), GURL("http://www.blocker.com"), 2);
76  ui_test_utils::NavigateToURLWithDisposition(
77        browser(), GURL("http://www.opener.com/#cnn?q=b"), NEW_WINDOW,
78        ui_test_utils::BROWSER_TEST_NONE);
79  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
80      browser(), GURL("http://www.blocker.com"), 2);
81
82  for (int i = UmaPolicy::NONE + 1; i < UmaPolicy::MAX_STATUS - 2; ++i) {
83    base::HistogramBase* google_histogram = base::Histogram::FactoryGet(
84        ConcatNames(kGooglePrefix, i),
85        1, 100, 50, base::HistogramBase::kNoFlags);
86    scoped_ptr<base::HistogramSamples> google_samples =
87        google_histogram->SnapshotSamples();
88    EXPECT_EQ(3, google_samples->TotalCount());
89    EXPECT_EQ(3, google_samples->GetCount(1));
90
91    base::HistogramBase* cnn_histogram = base::Histogram::FactoryGet(
92        ConcatNames(kNonGooglePrefix, i),
93        1, 100, 50, base::HistogramBase::kNoFlags);
94    scoped_ptr<base::HistogramSamples> cnn_samples =
95        cnn_histogram->SnapshotSamples();
96    if (ConcatNames(kNonGooglePrefix, i) != "ExtensionActivity.ContentScript" &&
97        ConcatNames(kNonGooglePrefix, i) != "ExtensionActivity.ReadDom") {
98      // There's a content script on opener.com that checks the location.
99      // The test is not set up to accurately record opener.com histograms due
100      // to the possibility of race conditions in the testing framework, so we
101      // can't check those values.
102      EXPECT_EQ(2, cnn_samples->GetCount(1));
103    }
104  }
105}
106
107// Two windows are open at once with the same google.com TLD.
108// However, they should be treated separately because they have different URLs.
109IN_PROC_BROWSER_TEST_F(
110    ActivityLogUmaPolicyTest, DISABLED_ParallelDistinctNavs) {
111  host_resolver()->AddRule("*", "127.0.0.1");
112  StartEmbeddedTestServer();
113
114  const extensions::Extension* ext =
115      LoadExtension(test_data_dir_.AppendASCII("uma_policy"));
116  ASSERT_TRUE(ext);
117
118  ui_test_utils::NavigateToURLWithDisposition(
119        browser(), GURL("http://www.opener.com/#google?p=a"), NEW_WINDOW,
120        ui_test_utils::BROWSER_TEST_NONE);
121  ui_test_utils::NavigateToURLWithDisposition(
122        browser(), GURL("http://www.opener.com/#google?p=b"), NEW_WINDOW,
123        ui_test_utils::BROWSER_TEST_NONE);
124  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
125      browser(), GURL("http://www.blocker.com"), 2);
126
127  for (int i = UmaPolicy::NONE + 1; i < UmaPolicy::MAX_STATUS - 2; ++i) {
128    base::HistogramBase* google_histogram = base::Histogram::FactoryGet(
129        ConcatNames(kGooglePrefix, i),
130        1, 100, 50, base::HistogramBase::kNoFlags);
131    scoped_ptr<base::HistogramSamples> google_samples =
132        google_histogram->SnapshotSamples();
133    EXPECT_EQ(2, google_samples->GetCount(1));
134  }
135}
136
137// Two windows are open at once with the same Google URLs.
138// They should be treated the same.
139IN_PROC_BROWSER_TEST_F(ActivityLogUmaPolicyTest, DISABLED_Google_ParallelSame) {
140  host_resolver()->AddRule("*", "127.0.0.1");
141  StartEmbeddedTestServer();
142
143  const extensions::Extension* ext =
144      LoadExtension(test_data_dir_.AppendASCII("uma_policy"));
145  ASSERT_TRUE(ext);
146
147  ui_test_utils::NavigateToURLWithDisposition(
148        browser(), GURL("http://www.opener.com/#googlea"), NEW_WINDOW,
149        ui_test_utils::BROWSER_TEST_NONE);
150  ui_test_utils::NavigateToURLWithDisposition(
151        browser(), GURL("http://www.opener.com/#googleb"), NEW_WINDOW,
152        ui_test_utils::BROWSER_TEST_NONE);
153  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
154      browser(), GURL("http://www.blocker.com"), 2);
155
156  for (int i = UmaPolicy::NONE + 1; i < UmaPolicy::MAX_STATUS - 2; ++i) {
157    base::HistogramBase* google_histogram = base::Histogram::FactoryGet(
158        ConcatNames(kGooglePrefix, i),
159        1, 100, 50, base::HistogramBase::kNoFlags);
160    scoped_ptr<base::HistogramSamples> google_samples =
161        google_histogram->SnapshotSamples();
162    EXPECT_EQ(1, google_samples->GetCount(1));
163  }
164}
165
166// Two windows are open at once with the same non-Google URLs.
167// They should be treated the same.
168IN_PROC_BROWSER_TEST_F(ActivityLogUmaPolicyTest,
169    DISABLED_NonGoogle_ParallelSame) {
170  host_resolver()->AddRule("*", "127.0.0.1");
171  StartEmbeddedTestServer();
172
173  const extensions::Extension* ext =
174      LoadExtension(test_data_dir_.AppendASCII("uma_policy"));
175  ASSERT_TRUE(ext);
176
177  ui_test_utils::NavigateToURLWithDisposition(
178        browser(), GURL("http://www.opener.com/#cnna"), NEW_WINDOW,
179        ui_test_utils::BROWSER_TEST_NONE);
180  ui_test_utils::NavigateToURLWithDisposition(
181        browser(), GURL("http://www.opener.com/#cnnb"), NEW_WINDOW,
182        ui_test_utils::BROWSER_TEST_NONE);
183  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
184      browser(), GURL("http://www.blocker.com"), 2);
185
186  for (int i = UmaPolicy::NONE + 1; i < UmaPolicy::MAX_STATUS - 2; ++i) {
187    base::HistogramBase* cnn_histogram = base::Histogram::FactoryGet(
188        ConcatNames(kNonGooglePrefix, i),
189        1, 100, 50, base::HistogramBase::kNoFlags);
190    scoped_ptr<base::HistogramSamples> cnn_samples =
191        cnn_histogram->SnapshotSamples();
192    if (ConcatNames(kNonGooglePrefix, i) != "ExtensionActivity.ContentScript" &&
193        ConcatNames(kNonGooglePrefix, i) != "ExtensionActivity.ReadDom") {
194      // There's a content script on opener.com that checks the location.
195      // The test is not set up to accurately record opener.com histograms due
196      // to the possibility of race conditions in the testing framework, so we
197      // can't check those values.
198      EXPECT_EQ(1, cnn_samples->GetCount(1));
199    }
200  }
201}
202
203// This runs with multiple extensions installed.
204IN_PROC_BROWSER_TEST_F(ActivityLogUmaPolicyTest, DISABLED_MultipleExtensions) {
205  host_resolver()->AddRule("*", "127.0.0.1");
206  StartEmbeddedTestServer();
207
208  const extensions::Extension* ext =
209      LoadExtension(test_data_dir_.AppendASCII("uma_policy"));
210  ASSERT_TRUE(ext);
211
212  const char* script2 =
213      "document.createElement('script');"
214      "document.createElement('iframe');"
215      "document.createElement('div');"
216      "document.createElement('embed');"
217      "document.createElement('object');";
218
219  const char* manifest =
220      "{"
221      "  \"name\": \"Activity Log UMA Policy Test Extension\","
222      "  \"version\": \"0.%s\","
223      "  \"description\": \"Testing the histogramming\","
224      "  \"content_scripts\": ["
225      "      {"
226      "        \"matches\": "
227      "            [\"http://www.google.com/*\","
228      "             \"http://www.cnn.com/*\"],"
229      "        \"js\": [\"content_script.js\"]"
230      "      }"
231      "    ],"
232      "  \"manifest_version\": 2"
233      "}";
234
235  extensions::TestExtensionDir dir2;
236  dir2.WriteManifest(base::StringPrintf(manifest, "2"));
237  dir2.WriteFile(FILE_PATH_LITERAL("content_script.js"), script2);
238  LoadExtension(dir2.unpacked_path());
239
240  ui_test_utils::NavigateToURLWithDisposition(
241        browser(), GURL("http://www.opener.com/#google"), NEW_WINDOW,
242        ui_test_utils::BROWSER_TEST_NONE);
243  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
244      browser(), GURL("http://www.blocker.com"), 2);
245  ui_test_utils::NavigateToURLWithDisposition(
246        browser(), GURL("http://www.opener.com/#cnn?q=b"), NEW_WINDOW,
247        ui_test_utils::BROWSER_TEST_NONE);
248  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
249      browser(), GURL("http://www.blocker.com"), 2);
250
251  const char* subset_one[] = {
252      "CreatedLink",
253      "InnerHtml",
254      "DocumentWrite"
255  };
256
257  const char* subset_two[] = {
258      "ContentScript",
259      "CreatedScript",
260      "CreatedIframe",
261      "CreatedDiv",
262      "CreatedEmbed",
263      "CreatedObject",
264      "InvokedDomMethod"
265  };
266
267  // These were only touched by one of the scripts.
268  for (size_t i = 0; i < arraysize(subset_one); ++i) {
269    base::HistogramBase* google_histogram = base::Histogram::FactoryGet(
270        std::string(kGooglePrefix) + "." + std::string(subset_one[i]),
271        1, 100, 50, base::HistogramBase::kNoFlags);
272    scoped_ptr<base::HistogramSamples> google_samples =
273        google_histogram->SnapshotSamples();
274    EXPECT_EQ(1, google_samples->GetCount(1));
275
276    base::HistogramBase* cnn_histogram = base::Histogram::FactoryGet(
277        std::string(kNonGooglePrefix) + "." + std::string(subset_one[i]),
278        1, 100, 50, base::HistogramBase::kNoFlags);
279    scoped_ptr<base::HistogramSamples> cnn_samples =
280        cnn_histogram->SnapshotSamples();
281    EXPECT_EQ(1, cnn_samples->GetCount(1));
282  }
283
284  // These were touched by both scripts.
285  for (size_t i = 0; i < arraysize(subset_two); ++i) {
286    base::HistogramBase* google_histogram = base::Histogram::FactoryGet(
287        std::string(kGooglePrefix) + "." + std::string(subset_two[i]),
288        1, 100, 50, base::HistogramBase::kNoFlags);
289    scoped_ptr<base::HistogramSamples> google_samples =
290        google_histogram->SnapshotSamples();
291    EXPECT_EQ(1, google_samples->GetCount(2));
292
293    base::HistogramBase* cnn_histogram = base::Histogram::FactoryGet(
294        std::string(kNonGooglePrefix) + "." + std::string(subset_two[i]),
295        1, 100, 50, base::HistogramBase::kNoFlags);
296    scoped_ptr<base::HistogramSamples> cnn_samples =
297        cnn_histogram->SnapshotSamples();
298    EXPECT_EQ(1, cnn_samples->GetCount(2));
299  }
300
301}
302