1 // Copyright 2015 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.
5 #include "chrome/browser/site_details.h"
7 #include "base/bind_helpers.h"
8 #include "base/files/file_path.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/path_service.h"
11 #include "base/test/histogram_tester.h"
12 #include "chrome/browser/extensions/extension_browsertest.h"
13 #include "chrome/browser/extensions/test_extension_dir.h"
14 #include "chrome/browser/metrics/metrics_memory_details.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/url_constants.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "content/public/browser/notification_service.h"
21 #include "content/public/test/browser_test_utils.h"
22 #include "content/public/test/test_utils.h"
23 #include "extensions/common/value_builder.h"
24 #include "net/dns/mock_host_resolver.h"
25 #include "net/test/embedded_test_server/embedded_test_server.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
30 using content::WebContents
;
31 using extensions::DictionaryBuilder
;
32 using extensions::Extension
;
33 using extensions::ListBuilder
;
34 using extensions::TestExtensionDir
;
35 using testing::ContainerEq
;
36 using testing::ElementsAre
;
40 class TestMemoryDetails
: public MetricsMemoryDetails
{
43 : MetricsMemoryDetails(base::Bind(&base::DoNothing
), nullptr) {}
45 void StartFetchAndWait() {
46 uma_
.reset(new base::HistogramTester());
47 StartFetch(FROM_CHROME_ONLY
);
48 content::RunMessageLoop();
51 // Returns a HistogramTester which observed the most recent call to
52 // StartFetchAndWait().
53 base::HistogramTester
* uma() { return uma_
.get(); }
56 ~TestMemoryDetails() override
{}
58 void OnDetailsAvailable() override
{
59 MetricsMemoryDetails::OnDetailsAvailable();
60 // Exit the loop initiated by StartFetchAndWait().
61 base::MessageLoop::current()->Quit();
64 scoped_ptr
<base::HistogramTester
> uma_
;
66 DISALLOW_COPY_AND_ASSIGN(TestMemoryDetails
);
71 class SiteDetailsBrowserTest
: public ExtensionBrowserTest
{
73 SiteDetailsBrowserTest() {}
74 ~SiteDetailsBrowserTest() override
{}
76 void SetUpOnMainThread() override
{
77 host_resolver()->AddRule("*", "127.0.0.1");
79 // Add content/test/data so we can use cross_site_iframe_factory.html
80 base::FilePath test_data_dir
;
81 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &test_data_dir
));
82 embedded_test_server()->ServeFilesFromDirectory(
83 test_data_dir
.AppendASCII("content/test/data/"));
84 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
87 // Create and install an extension that has a couple of web-accessible
88 // resources and, optionally, a background process.
89 const Extension
* CreateExtension(const std::string
& name
,
90 bool has_background_process
) {
91 scoped_ptr
<TestExtensionDir
> dir(new TestExtensionDir
);
93 DictionaryBuilder manifest
;
94 manifest
.Set("name", name
)
95 .Set("version", "1.0")
96 .Set("manifest_version", 2)
97 .Set("web_accessible_resources", ListBuilder()
98 .Append("blank_iframe.html")
99 .Append("http_iframe.html"));
101 if (has_background_process
) {
102 manifest
.Set("background",
103 DictionaryBuilder().Set("scripts",
104 ListBuilder().Append("script.js")));
105 dir
->WriteFile(FILE_PATH_LITERAL("script.js"),
106 "console.log('" + name
+ " running');");
109 dir
->WriteFile(FILE_PATH_LITERAL("blank_iframe.html"),
110 "<html><body>" + name
+
112 "<iframe width=40 height=40></iframe></body></html>");
113 GURL iframe_url
= embedded_test_server()->GetURL("w.com", "/title1.html");
114 dir
->WriteFile(FILE_PATH_LITERAL("http_iframe.html"),
115 "<html><body>" + name
+
117 "<iframe width=40 height=40 src='" +
118 iframe_url
.spec() + "'></iframe></body></html>");
119 dir
->WriteManifest(manifest
.ToJSON());
121 const Extension
* extension
= LoadExtension(dir
->unpacked_path());
122 EXPECT_TRUE(extension
);
123 temp_dirs_
.push_back(dir
.release());
128 ScopedVector
<TestExtensionDir
> temp_dirs_
;
129 DISALLOW_COPY_AND_ASSIGN(SiteDetailsBrowserTest
);
132 // Test the accuracy of SiteDetails process estimation, in the presence of
133 // multiple iframes, navigation, multiple BrowsingInstances, and multiple tabs
134 // in the same BrowsingInstance.
135 IN_PROC_BROWSER_TEST_F(SiteDetailsBrowserTest
, ManyIframes
) {
136 // Page with 14 nested oopifs across 9 sites (a.com through i.com).
137 // None of these are https.
138 GURL abcdefghi_url
= embedded_test_server()->GetURL(
140 "/cross_site_iframe_factory.html?a(b(a(b,c,d,e,f,g,h)),c,d,e,i(f))");
141 ui_test_utils::NavigateToURL(browser(), abcdefghi_url
);
144 scoped_refptr
<TestMemoryDetails
> details
= new TestMemoryDetails();
145 details
->StartFetchAndWait();
148 details
->uma()->GetAllSamples("SiteIsolation.BrowsingInstanceCount"),
149 ElementsAre(Bucket(1, 1)));
150 EXPECT_THAT(details
->uma()->GetAllSamples(
151 "SiteIsolation.CurrentRendererProcessCount"),
152 ElementsAre(Bucket(1, 1)));
153 EXPECT_THAT(details
->uma()->GetAllSamples(
154 "SiteIsolation.IsolateAllSitesProcessCountEstimate"),
155 ElementsAre(Bucket(9, 1)));
156 EXPECT_THAT(details
->uma()->GetAllSamples(
157 "SiteIsolation.IsolateAllSitesProcessCountLowerBound"),
158 ElementsAre(Bucket(9, 1)));
159 EXPECT_THAT(details
->uma()->GetAllSamples(
160 "SiteIsolation.IsolateAllSitesProcessCountNoLimit"),
161 ElementsAre(Bucket(9, 1)));
162 EXPECT_THAT(details
->uma()->GetAllSamples(
163 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate"),
164 ElementsAre(Bucket(1, 1)));
165 EXPECT_THAT(details
->uma()->GetAllSamples(
166 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound"),
167 ElementsAre(Bucket(1, 1)));
168 EXPECT_THAT(details
->uma()->GetAllSamples(
169 "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit"),
170 ElementsAre(Bucket(1, 1)));
171 EXPECT_THAT(details
->uma()->GetAllSamples(
172 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
173 ElementsAre(Bucket(1, 1)));
174 EXPECT_THAT(details
->uma()->GetAllSamples(
175 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
176 ElementsAre(Bucket(1, 1)));
177 EXPECT_THAT(details
->uma()->GetAllSamples(
178 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
179 ElementsAre(Bucket(1, 1)));
181 // Navigate to a different, disjoint set of 7 sites.
182 GURL pqrstuv_url
= embedded_test_server()->GetURL(
184 "/cross_site_iframe_factory.html?p(q(r),r(s),s(t),t(q),u(u),v(p))");
185 ui_test_utils::NavigateToURL(browser(), pqrstuv_url
);
187 details
= new TestMemoryDetails();
188 details
->StartFetchAndWait();
191 details
->uma()->GetAllSamples("SiteIsolation.BrowsingInstanceCount"),
192 ElementsAre(Bucket(1, 1)));
193 EXPECT_THAT(details
->uma()->GetAllSamples(
194 "SiteIsolation.CurrentRendererProcessCount"),
195 ElementsAre(Bucket(1, 1)));
196 EXPECT_THAT(details
->uma()->GetAllSamples(
197 "SiteIsolation.IsolateAllSitesProcessCountEstimate"),
198 ElementsAre(Bucket(7, 1)));
199 EXPECT_THAT(details
->uma()->GetAllSamples(
200 "SiteIsolation.IsolateAllSitesProcessCountLowerBound"),
201 ElementsAre(Bucket(7, 1)));
202 EXPECT_THAT(details
->uma()->GetAllSamples(
203 "SiteIsolation.IsolateAllSitesProcessCountNoLimit"),
204 ElementsAre(Bucket(7, 1)));
205 EXPECT_THAT(details
->uma()->GetAllSamples(
206 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate"),
207 ElementsAre(Bucket(1, 1)));
208 EXPECT_THAT(details
->uma()->GetAllSamples(
209 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound"),
210 ElementsAre(Bucket(1, 1)));
211 EXPECT_THAT(details
->uma()->GetAllSamples(
212 "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit"),
213 ElementsAre(Bucket(1, 1)));
214 EXPECT_THAT(details
->uma()->GetAllSamples(
215 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
216 ElementsAre(Bucket(1, 1)));
217 EXPECT_THAT(details
->uma()->GetAllSamples(
218 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
219 ElementsAre(Bucket(1, 1)));
220 EXPECT_THAT(details
->uma()->GetAllSamples(
221 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
222 ElementsAre(Bucket(1, 1)));
224 // Open a second tab (different BrowsingInstance) with 4 sites (a through d).
225 GURL abcd_url
= embedded_test_server()->GetURL(
226 "a.com", "/cross_site_iframe_factory.html?a(b(c(d())))");
227 AddTabAtIndex(1, abcd_url
, ui::PAGE_TRANSITION_TYPED
);
229 details
= new TestMemoryDetails();
230 details
->StartFetchAndWait();
233 details
->uma()->GetAllSamples("SiteIsolation.BrowsingInstanceCount"),
234 ElementsAre(Bucket(2, 1)));
235 EXPECT_THAT(details
->uma()->GetAllSamples(
236 "SiteIsolation.CurrentRendererProcessCount"),
237 ElementsAre(Bucket(2, 1)));
238 EXPECT_THAT(details
->uma()->GetAllSamples(
239 "SiteIsolation.IsolateAllSitesProcessCountEstimate"),
240 ElementsAre(Bucket(11, 1)));
241 EXPECT_THAT(details
->uma()->GetAllSamples(
242 "SiteIsolation.IsolateAllSitesProcessCountLowerBound"),
243 ElementsAre(Bucket(11, 1)));
244 EXPECT_THAT(details
->uma()->GetAllSamples(
245 "SiteIsolation.IsolateAllSitesProcessCountNoLimit"),
246 ElementsAre(Bucket(11, 1)));
247 EXPECT_THAT(details
->uma()->GetAllSamples(
248 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate"),
249 ElementsAre(Bucket(2, 1)));
250 EXPECT_THAT(details
->uma()->GetAllSamples(
251 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound"),
252 ElementsAre(Bucket(1, 1))); // TODO(nick): This should be 2.
253 EXPECT_THAT(details
->uma()->GetAllSamples(
254 "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit"),
255 ElementsAre(Bucket(2, 1)));
256 EXPECT_THAT(details
->uma()->GetAllSamples(
257 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
258 ElementsAre(Bucket(2, 1)));
259 EXPECT_THAT(details
->uma()->GetAllSamples(
260 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
261 ElementsAre(Bucket(1, 1)));
262 EXPECT_THAT(details
->uma()->GetAllSamples(
263 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
264 ElementsAre(Bucket(2, 1)));
266 // Open a third tab (different BrowsingInstance) with the same 4 sites.
267 AddTabAtIndex(2, abcd_url
, ui::PAGE_TRANSITION_TYPED
);
269 details
= new TestMemoryDetails();
270 details
->StartFetchAndWait();
273 details
->uma()->GetAllSamples("SiteIsolation.BrowsingInstanceCount"),
274 ElementsAre(Bucket(3, 1)));
275 EXPECT_THAT(details
->uma()->GetAllSamples(
276 "SiteIsolation.CurrentRendererProcessCount"),
277 ElementsAre(Bucket(3, 1)));
278 // Could be 11 if subframe processes were reused across BrowsingInstances.
279 EXPECT_THAT(details
->uma()->GetAllSamples(
280 "SiteIsolation.IsolateAllSitesProcessCountEstimate"),
281 ElementsAre(Bucket(15, 1)));
282 EXPECT_THAT(details
->uma()->GetAllSamples(
283 "SiteIsolation.IsolateAllSitesProcessCountLowerBound"),
284 ElementsAre(Bucket(11, 1)));
285 EXPECT_THAT(details
->uma()->GetAllSamples(
286 "SiteIsolation.IsolateAllSitesProcessCountNoLimit"),
287 ElementsAre(Bucket(15, 1)));
288 EXPECT_THAT(details
->uma()->GetAllSamples(
289 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate"),
290 ElementsAre(Bucket(3, 1)));
291 EXPECT_THAT(details
->uma()->GetAllSamples(
292 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound"),
293 ElementsAre(Bucket(1, 1))); // TODO(nick): This should be 3.
294 EXPECT_THAT(details
->uma()->GetAllSamples(
295 "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit"),
296 ElementsAre(Bucket(3, 1)));
297 EXPECT_THAT(details
->uma()->GetAllSamples(
298 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
299 ElementsAre(Bucket(3, 1)));
300 EXPECT_THAT(details
->uma()->GetAllSamples(
301 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
302 ElementsAre(Bucket(1, 1)));
303 EXPECT_THAT(details
->uma()->GetAllSamples(
304 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
305 ElementsAre(Bucket(3, 1)));
307 // From the third tab, window.open() a fourth tab in the same
308 // BrowsingInstance, to a page using the same four sites "a-d" as third tab,
309 // plus an additional site "e". The estimated process counts should increase
310 // by one (not five) from the previous scenario, as the new tab can reuse the
311 // four processes already in the BrowsingInstance.
312 GURL dcbae_url
= embedded_test_server()->GetURL(
313 "a.com", "/cross_site_iframe_factory.html?d(c(b(a(e))))");
314 ui_test_utils::UrlLoadObserver
load_complete(
315 dcbae_url
, content::NotificationService::AllSources());
316 ASSERT_EQ(3, browser()->tab_strip_model()->count());
317 ASSERT_TRUE(content::ExecuteScript(
318 browser()->tab_strip_model()->GetActiveWebContents(),
319 "window.open('" + dcbae_url
.spec() + "');"));
320 ASSERT_EQ(4, browser()->tab_strip_model()->count());
321 load_complete
.Wait();
323 details
= new TestMemoryDetails();
324 details
->StartFetchAndWait();
327 details
->uma()->GetAllSamples("SiteIsolation.BrowsingInstanceCount"),
328 ElementsAre(Bucket(3, 1)));
329 EXPECT_THAT(details
->uma()->GetAllSamples(
330 "SiteIsolation.CurrentRendererProcessCount"),
331 ElementsAre(Bucket(3, 1)));
332 // Could be 11 if subframe processes were reused across BrowsingInstances.
333 EXPECT_THAT(details
->uma()->GetAllSamples(
334 "SiteIsolation.IsolateAllSitesProcessCountEstimate"),
335 ElementsAre(Bucket(16, 1)));
336 EXPECT_THAT(details
->uma()->GetAllSamples(
337 "SiteIsolation.IsolateAllSitesProcessCountLowerBound"),
338 ElementsAre(Bucket(12, 1)));
339 EXPECT_THAT(details
->uma()->GetAllSamples(
340 "SiteIsolation.IsolateAllSitesProcessCountNoLimit"),
341 ElementsAre(Bucket(16, 1)));
342 EXPECT_THAT(details
->uma()->GetAllSamples(
343 "SiteIsolation.IsolateHttpsSitesProcessCountEstimate"),
344 ElementsAre(Bucket(3, 1)));
345 EXPECT_THAT(details
->uma()->GetAllSamples(
346 "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound"),
347 ElementsAre(Bucket(1, 1))); // TODO(nick): This should be 3.
348 EXPECT_THAT(details
->uma()->GetAllSamples(
349 "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit"),
350 ElementsAre(Bucket(3, 1)));
351 EXPECT_THAT(details
->uma()->GetAllSamples(
352 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
353 ElementsAre(Bucket(3, 1)));
354 EXPECT_THAT(details
->uma()->GetAllSamples(
355 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
356 ElementsAre(Bucket(1, 1)));
357 EXPECT_THAT(details
->uma()->GetAllSamples(
358 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
359 ElementsAre(Bucket(3, 1)));
362 IN_PROC_BROWSER_TEST_F(SiteDetailsBrowserTest
, IsolateExtensions
) {
363 // We start on "about:blank", which should be credited with a process in this
365 scoped_refptr
<TestMemoryDetails
> details
= new TestMemoryDetails();
366 details
->StartFetchAndWait();
367 EXPECT_THAT(details
->uma()->GetAllSamples(
368 "SiteIsolation.CurrentRendererProcessCount"),
369 ElementsAre(Bucket(1, 1)));
370 EXPECT_THAT(details
->uma()->GetAllSamples(
371 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
372 ElementsAre(Bucket(1, 1)));
373 EXPECT_THAT(details
->uma()->GetAllSamples(
374 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
375 ElementsAre(Bucket(1, 1)));
376 EXPECT_THAT(details
->uma()->GetAllSamples(
377 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
378 ElementsAre(Bucket(1, 1)));
380 // Install one script-injecting extension with background page, and an
381 // extension with web accessible resources.
382 const Extension
* extension1
= CreateExtension("Extension One", true);
383 const Extension
* extension2
= CreateExtension("Extension Two", false);
385 // Open two a.com tabs (with cross site http iframes). IsolateExtensions mode
386 // should have no effect so far, since there are no frames straddling the
387 // extension/web boundary.
388 GURL tab1_url
= embedded_test_server()->GetURL(
389 "a.com", "/cross_site_iframe_factory.html?a(b,c)");
390 ui_test_utils::NavigateToURL(browser(), tab1_url
);
391 WebContents
* tab1
= browser()->tab_strip_model()->GetWebContentsAt(0);
392 GURL tab2_url
= embedded_test_server()->GetURL(
393 "a.com", "/cross_site_iframe_factory.html?a(d,e)");
394 AddTabAtIndex(1, tab2_url
, ui::PAGE_TRANSITION_TYPED
);
395 WebContents
* tab2
= browser()->tab_strip_model()->GetWebContentsAt(1);
397 details
= new TestMemoryDetails();
398 details
->StartFetchAndWait();
399 EXPECT_THAT(details
->uma()->GetAllSamples(
400 "SiteIsolation.CurrentRendererProcessCount"),
401 ElementsAre(Bucket(3, 1)));
402 EXPECT_THAT(details
->uma()->GetAllSamples(
403 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
404 ElementsAre(Bucket(3, 1)));
405 EXPECT_THAT(details
->uma()->GetAllSamples(
406 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
407 ElementsAre(Bucket(2, 1)));
408 EXPECT_THAT(details
->uma()->GetAllSamples(
409 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
410 ElementsAre(Bucket(3, 1)));
412 // Test that "one process per extension" applies even when web content has an
415 // Tab1 navigates its first iframe to a resource of extension1. This shouldn't
416 // result in a new extension process (it should share with extension1's
418 content::NavigateIframeToURL(
419 tab1
, "child-0", extension1
->GetResourceURL("/blank_iframe.html"));
420 details
= new TestMemoryDetails();
421 details
->StartFetchAndWait();
422 EXPECT_THAT(details
->uma()->GetAllSamples(
423 "SiteIsolation.CurrentRendererProcessCount"),
424 ElementsAre(Bucket(3, 1)));
425 EXPECT_THAT(details
->uma()->GetAllSamples(
426 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
427 ElementsAre(Bucket(3, 1)));
428 EXPECT_THAT(details
->uma()->GetAllSamples(
429 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
430 ElementsAre(Bucket(2, 1)));
431 EXPECT_THAT(details
->uma()->GetAllSamples(
432 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
433 ElementsAre(Bucket(3, 1)));
435 // Tab2 navigates its first iframe to a resource of extension1. This also
436 // shouldn't result in a new extension process (it should share with the
437 // background page and the other iframe).
438 content::NavigateIframeToURL(
439 tab2
, "child-0", extension1
->GetResourceURL("/blank_iframe.html"));
440 details
= new TestMemoryDetails();
441 details
->StartFetchAndWait();
442 EXPECT_THAT(details
->uma()->GetAllSamples(
443 "SiteIsolation.CurrentRendererProcessCount"),
444 ElementsAre(Bucket(3, 1)));
445 EXPECT_THAT(details
->uma()->GetAllSamples(
446 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
447 ElementsAre(Bucket(3, 1)));
448 EXPECT_THAT(details
->uma()->GetAllSamples(
449 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
450 ElementsAre(Bucket(2, 1)));
451 EXPECT_THAT(details
->uma()->GetAllSamples(
452 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
453 ElementsAre(Bucket(3, 1)));
455 // Tab1 navigates its second iframe to a resource of extension2. This SHOULD
456 // result in a new process since extension2 had no existing process.
457 content::NavigateIframeToURL(
458 tab1
, "child-1", extension2
->GetResourceURL("/blank_iframe.html"));
459 details
= new TestMemoryDetails();
460 details
->StartFetchAndWait();
461 EXPECT_THAT(details
->uma()->GetAllSamples(
462 "SiteIsolation.CurrentRendererProcessCount"),
463 ElementsAre(Bucket(3, 1)));
464 EXPECT_THAT(details
->uma()->GetAllSamples(
465 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
466 ElementsAre(Bucket(4, 1)));
467 EXPECT_THAT(details
->uma()->GetAllSamples(
468 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
469 ElementsAre(Bucket(3, 1)));
470 EXPECT_THAT(details
->uma()->GetAllSamples(
471 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
472 ElementsAre(Bucket(4, 1)));
474 // Tab2 navigates its second iframe to a resource of extension2. This should
475 // share the existing extension2 process.
476 content::NavigateIframeToURL(
477 tab2
, "child-1", extension2
->GetResourceURL("/blank_iframe.html"));
478 details
= new TestMemoryDetails();
479 details
->StartFetchAndWait();
480 EXPECT_THAT(details
->uma()->GetAllSamples(
481 "SiteIsolation.CurrentRendererProcessCount"),
482 ElementsAre(Bucket(3, 1)));
483 EXPECT_THAT(details
->uma()->GetAllSamples(
484 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
485 ElementsAre(Bucket(4, 1)));
486 EXPECT_THAT(details
->uma()->GetAllSamples(
487 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
488 ElementsAre(Bucket(3, 1)));
489 EXPECT_THAT(details
->uma()->GetAllSamples(
490 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
491 ElementsAre(Bucket(4, 1)));
493 // Install extension3 (identical config to extension2)
494 const Extension
* extension3
= CreateExtension("Extension Three", false);
496 // Navigate Tab2 to a top-level page from extension3. There are four processes
497 // now: one for tab1's main frame, and one for each of the extensions:
498 // extension1 has a process because it has a background page; extension2 is
499 // used as an iframe in tab1, and extension3 is the top-level frame in tab2.
500 ui_test_utils::NavigateToURL(browser(),
501 extension3
->GetResourceURL("blank_iframe.html"));
502 details
= new TestMemoryDetails();
503 details
->StartFetchAndWait();
504 EXPECT_THAT(details
->uma()->GetAllSamples(
505 "SiteIsolation.CurrentRendererProcessCount"),
506 ElementsAre(Bucket(3, 1)));
507 EXPECT_THAT(details
->uma()->GetAllSamples(
508 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
509 ElementsAre(Bucket(4, 1)));
510 EXPECT_THAT(details
->uma()->GetAllSamples(
511 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
512 ElementsAre(Bucket(4, 1)));
513 EXPECT_THAT(details
->uma()->GetAllSamples(
514 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
515 ElementsAre(Bucket(4, 1)));
517 // Navigate tab2 to a different extension3 page containing a web iframe. The
518 // iframe should get its own process. The lower bound number indicates that,
519 // in theory, the iframe could share a process with tab1's main frame.
520 ui_test_utils::NavigateToURL(browser(),
521 extension3
->GetResourceURL("http_iframe.html"));
522 details
= new TestMemoryDetails();
523 details
->StartFetchAndWait();
524 EXPECT_THAT(details
->uma()->GetAllSamples(
525 "SiteIsolation.CurrentRendererProcessCount"),
526 ElementsAre(Bucket(3, 1)));
527 EXPECT_THAT(details
->uma()->GetAllSamples(
528 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
529 ElementsAre(Bucket(5, 1)));
530 EXPECT_THAT(details
->uma()->GetAllSamples(
531 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
532 ElementsAre(Bucket(4, 1)));
533 EXPECT_THAT(details
->uma()->GetAllSamples(
534 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
535 ElementsAre(Bucket(5, 1)));
537 // Navigate tab1 to an extension3 page with an extension3 iframe. There should
538 // be three processes estimated by IsolateExtensions: one for extension3, one
539 // for extension1's background page, and one for the web iframe in tab2.
540 browser()->tab_strip_model()->ActivateTabAt(0, true);
541 ui_test_utils::NavigateToURL(browser(),
542 extension3
->GetResourceURL("blank_iframe.html"));
543 details
= new TestMemoryDetails();
544 details
->StartFetchAndWait();
545 EXPECT_THAT(details
->uma()->GetAllSamples(
546 "SiteIsolation.CurrentRendererProcessCount"),
547 ElementsAre(Bucket(2, 1)));
548 EXPECT_THAT(details
->uma()->GetAllSamples(
549 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
550 ElementsAre(Bucket(3, 1)));
551 EXPECT_THAT(details
->uma()->GetAllSamples(
552 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
553 ElementsAre(Bucket(3, 1)));
554 EXPECT_THAT(details
->uma()->GetAllSamples(
555 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
556 ElementsAre(Bucket(3, 1)));
558 // Now navigate tab1 to an extension3 page with a web iframe. This could share
559 // a process with tab2's iframe (the LowerBound number), or it could get its
560 // own process (the Estimate number).
561 ui_test_utils::NavigateToURL(browser(),
562 extension3
->GetResourceURL("http_iframe.html"));
563 details
= new TestMemoryDetails();
564 details
->StartFetchAndWait();
565 EXPECT_THAT(details
->uma()->GetAllSamples(
566 "SiteIsolation.CurrentRendererProcessCount"),
567 ElementsAre(Bucket(2, 1)));
568 EXPECT_THAT(details
->uma()->GetAllSamples(
569 "SiteIsolation.IsolateExtensionsProcessCountEstimate"),
570 ElementsAre(Bucket(4, 1)));
571 EXPECT_THAT(details
->uma()->GetAllSamples(
572 "SiteIsolation.IsolateExtensionsProcessCountLowerBound"),
573 ElementsAre(Bucket(3, 1)));
574 EXPECT_THAT(details
->uma()->GetAllSamples(
575 "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
576 ElementsAre(Bucket(4, 1)));