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 #include "content/browser/site_per_process_browsertest.h" | 5 #include "content/browser/site_per_process_browsertest.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 17 matching lines...) Expand all Loading... | |
28 #include "content/public/test/test_utils.h" | 28 #include "content/public/test/test_utils.h" |
29 #include "content/shell/browser/shell.h" | 29 #include "content/shell/browser/shell.h" |
30 #include "content/test/content_browser_test_utils_internal.h" | 30 #include "content/test/content_browser_test_utils_internal.h" |
31 #include "content/test/test_frame_navigation_observer.h" | 31 #include "content/test/test_frame_navigation_observer.h" |
32 #include "ipc/ipc_security_test_util.h" | 32 #include "ipc/ipc_security_test_util.h" |
33 #include "net/dns/mock_host_resolver.h" | 33 #include "net/dns/mock_host_resolver.h" |
34 #include "net/test/embedded_test_server/embedded_test_server.h" | 34 #include "net/test/embedded_test_server/embedded_test_server.h" |
35 | 35 |
36 namespace content { | 36 namespace content { |
37 | 37 |
38 namespace { | |
39 | |
40 // Helper function to send a postMessage and wait for a reply message. The | |
41 // |post_message_script| is executed on the |sender_ftn| frame, and the sender | |
42 // frame is expected to post |reply_status| from the DOMAutomationController | |
43 // when it receives a reply. | |
44 void PostMessageAndWaitForReply(FrameTreeNode* sender_ftn, | |
45 const std::string& post_message_script, | |
46 const std::string& reply_status) { | |
47 bool success = false; | |
48 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
49 sender_ftn->current_frame_host(), | |
50 "window.domAutomationController.send(" + post_message_script + ");", | |
51 &success)); | |
52 EXPECT_TRUE(success); | |
53 | |
54 content::DOMMessageQueue msg_queue; | |
55 std::string status; | |
56 while (msg_queue.WaitForMessage(&status)) { | |
57 if (status == reply_status) | |
58 break; | |
59 } | |
60 } | |
61 | |
62 } // anonymous namespace | |
63 | |
38 class RedirectNotificationObserver : public NotificationObserver { | 64 class RedirectNotificationObserver : public NotificationObserver { |
39 public: | 65 public: |
40 // Register to listen for notifications of the given type from either a | 66 // Register to listen for notifications of the given type from either a |
41 // specific source, or from all sources if |source| is | 67 // specific source, or from all sources if |source| is |
42 // NotificationService::AllSources(). | 68 // NotificationService::AllSources(). |
43 RedirectNotificationObserver(int notification_type, | 69 RedirectNotificationObserver(int notification_type, |
44 const NotificationSource& source); | 70 const NotificationSource& source); |
45 ~RedirectNotificationObserver() override; | 71 ~RedirectNotificationObserver() override; |
46 | 72 |
47 // Wait until the specified notification occurs. If the notification was | 73 // Wait until the specified notification occurs. If the notification was |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
848 EXPECT_EQ( | 874 EXPECT_EQ( |
849 " Site A ------------ proxies for B\n" | 875 " Site A ------------ proxies for B\n" |
850 " |--Site B ------- proxies for A\n" | 876 " |--Site B ------- proxies for A\n" |
851 " |--Site B ------- proxies for A\n" | 877 " |--Site B ------- proxies for A\n" |
852 " +--Site A ------- proxies for B\n" | 878 " +--Site A ------- proxies for B\n" |
853 "Where A = http://a.com/\n" | 879 "Where A = http://a.com/\n" |
854 " B = http://b.com/", | 880 " B = http://b.com/", |
855 DepictFrameTree(root)); | 881 DepictFrameTree(root)); |
856 | 882 |
857 // Check that third subframe's proxy is available in the b.com process by | 883 // Check that third subframe's proxy is available in the b.com process by |
858 // sending it a postMessage from second subframe. | 884 // sending it a postMessage from second subframe, and waiting for a reply. |
859 bool success = false; | 885 PostMessageAndWaitForReply(root->child_at(1), |
nasko
2015/05/04 17:16:55
I like the simplification of this helper function!
| |
860 EXPECT_TRUE(ExecuteScriptAndExtractBool( | 886 "postToSibling('subframe-msg','frame3')", |
861 root->child_at(1)->current_frame_host(), | 887 "\"done-frame2\""); |
862 "window.domAutomationController.send(" | |
863 " postToSibling('subframe-msg','frame3'));", | |
864 &success)); | |
865 EXPECT_TRUE(success); | |
866 | |
867 // Wait to receive a reply from third subframe. Second subframe sends | |
868 // "done-frame2" from the DOMAutomationController when the reply arrives. | |
869 content::DOMMessageQueue msg_queue; | |
870 std::string status; | |
871 while (msg_queue.WaitForMessage(&status)) { | |
872 if (status == "\"done-frame2\"") | |
873 break; | |
874 } | |
875 } | 888 } |
876 | 889 |
877 // In A-embed-B-embed-C scenario, verify that killing process B clears proxies | 890 // In A-embed-B-embed-C scenario, verify that killing process B clears proxies |
878 // of C from the tree. | 891 // of C from the tree. |
879 // | 892 // |
880 // 1 A A | 893 // 1 A A |
881 // / \ / \ / \ . | 894 // / \ / \ / \ . |
882 // 2 3 -> B A -> Kill B -> B* A | 895 // 2 3 -> B A -> Kill B -> B* A |
883 // / / | 896 // / / |
884 // 4 C | 897 // 4 C |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2092 GURL same_site_url(embedded_test_server()->GetURL("/post_message.html")); | 2105 GURL same_site_url(embedded_test_server()->GetURL("/post_message.html")); |
2093 EXPECT_EQ(same_site_url, root->child_at(0)->current_url()); | 2106 EXPECT_EQ(same_site_url, root->child_at(0)->current_url()); |
2094 GURL foo_url(embedded_test_server()->GetURL("foo.com", | 2107 GURL foo_url(embedded_test_server()->GetURL("foo.com", |
2095 "/post_message.html")); | 2108 "/post_message.html")); |
2096 EXPECT_EQ(foo_url, root->child_at(1)->current_url()); | 2109 EXPECT_EQ(foo_url, root->child_at(1)->current_url()); |
2097 EXPECT_NE(root->child_at(0)->current_frame_host()->GetSiteInstance(), | 2110 EXPECT_NE(root->child_at(0)->current_frame_host()->GetSiteInstance(), |
2098 root->child_at(1)->current_frame_host()->GetSiteInstance()); | 2111 root->child_at(1)->current_frame_host()->GetSiteInstance()); |
2099 | 2112 |
2100 // Send a message from first, same-site frame to second, cross-site frame. | 2113 // Send a message from first, same-site frame to second, cross-site frame. |
2101 // Expect the second frame to reply back to the first frame. | 2114 // Expect the second frame to reply back to the first frame. |
2102 // | 2115 PostMessageAndWaitForReply(root->child_at(0), |
2103 // TODO(alexmos): Also try sending from second to first frame. Currently, | 2116 "postToSibling('subframe-msg','subframe2')", |
2104 // this fails due to https://crbug.com/473518, which prevents | 2117 "\"done-subframe1\""); |
2105 // parent.frames[x] from working when "parent" is a remote frame. | |
2106 bool success = false; | |
2107 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
2108 root->child_at(0)->current_frame_host(), | |
2109 "window.domAutomationController.send(" | |
2110 " postToSibling('subframe-msg','subframe2'));", | |
2111 &success)); | |
2112 EXPECT_TRUE(success); | |
2113 | |
2114 // Wait for first frame to receive a reply from the second frame. It will | |
2115 // send "done-subframe1" from the DOMAutomationController when the reply | |
2116 // arrives. | |
2117 content::DOMMessageQueue msg_queue; | |
2118 std::string status; | |
2119 while (msg_queue.WaitForMessage(&status)) { | |
2120 if (status == "\"done-subframe1\"") | |
2121 break; | |
2122 } | |
2123 | 2118 |
2124 // Send a postMessage from second, cross-site frame to its parent. Expect | 2119 // Send a postMessage from second, cross-site frame to its parent. Expect |
2125 // parent to send a reply to the frame. | 2120 // parent to send a reply to the frame. |
2126 base::string16 expected_title(base::ASCIIToUTF16("subframe-msg")); | 2121 base::string16 expected_title(base::ASCIIToUTF16("subframe-msg")); |
2127 TitleWatcher title_watcher(shell()->web_contents(), expected_title); | 2122 TitleWatcher title_watcher(shell()->web_contents(), expected_title); |
2128 success = false; | 2123 PostMessageAndWaitForReply(root->child_at(1), "postToParent('subframe-msg')", |
2129 EXPECT_TRUE(ExecuteScriptAndExtractBool( | 2124 "\"done-subframe2\""); |
2130 root->child_at(1)->current_frame_host(), | |
2131 "window.domAutomationController.send(postToParent('subframe-msg'));", | |
2132 &success)); | |
2133 EXPECT_TRUE(success); | |
2134 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); | 2125 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); |
2135 | 2126 |
2136 // Wait for second frame to receive a reply from the parent. The frame will | |
2137 // return "done-subframe2" from the DOMAutomationController when the reply | |
2138 // arrives. | |
2139 while (msg_queue.WaitForMessage(&status)) { | |
2140 if (status == "\"done-subframe2\"") | |
2141 break; | |
2142 } | |
2143 | |
2144 // Verify the total number of received messages for each subframe. First | 2127 // Verify the total number of received messages for each subframe. First |
2145 // frame should have one message (reply from second frame), and second frame | 2128 // frame should have one message (reply from second frame), and second frame |
2146 // should have two messages (message from first frame and reply from parent). | 2129 // should have two messages (message from first frame and reply from parent). |
2147 int subframe1_received_messages = 0; | 2130 int subframe1_received_messages = 0; |
2148 int subframe2_received_messages = 0; | 2131 int subframe2_received_messages = 0; |
2149 EXPECT_TRUE(ExecuteScriptAndExtractInt( | 2132 EXPECT_TRUE(ExecuteScriptAndExtractInt( |
2150 root->child_at(0)->current_frame_host(), | 2133 root->child_at(0)->current_frame_host(), |
2151 "window.domAutomationController.send(window.receivedMessages);", | 2134 "window.domAutomationController.send(window.receivedMessages);", |
2152 &subframe1_received_messages)); | 2135 &subframe1_received_messages)); |
2153 EXPECT_EQ(1, subframe1_received_messages); | 2136 EXPECT_EQ(1, subframe1_received_messages); |
2154 EXPECT_TRUE(ExecuteScriptAndExtractInt( | 2137 EXPECT_TRUE(ExecuteScriptAndExtractInt( |
2155 root->child_at(1)->current_frame_host(), | 2138 root->child_at(1)->current_frame_host(), |
2156 "window.domAutomationController.send(window.receivedMessages);", | 2139 "window.domAutomationController.send(window.receivedMessages);", |
2157 &subframe2_received_messages)); | 2140 &subframe2_received_messages)); |
2158 EXPECT_EQ(2, subframe2_received_messages); | 2141 EXPECT_EQ(2, subframe2_received_messages); |
2159 } | 2142 } |
2160 | 2143 |
2144 // Check that parent.frames[num] references correct sibling frames when the | |
2145 // parent is remote. See https://crbug.com/478792. | |
2146 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, IndexedFrameAccess) { | |
2147 // Start on a page with three same-site subframes. | |
2148 GURL main_url( | |
2149 embedded_test_server()->GetURL("a.com", "/frame_tree/top.html")); | |
2150 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | |
2151 | |
2152 // It is safe to obtain the root frame tree node here, as it doesn't change. | |
2153 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | |
2154 ->GetFrameTree() | |
2155 ->root(); | |
2156 ASSERT_EQ(3U, root->child_count()); | |
2157 FrameTreeNode* child0 = root->child_at(0); | |
2158 FrameTreeNode* child1 = root->child_at(1); | |
2159 FrameTreeNode* child2 = root->child_at(2); | |
2160 | |
2161 // Send each of the frames to a different site. Each new renderer will first | |
2162 // create proxies for the parent and two sibling subframes and then create | |
2163 // and insert the new RenderFrame into the frame tree. | |
2164 GURL b_url(embedded_test_server()->GetURL("b.com", "/post_message.html")); | |
2165 GURL c_url(embedded_test_server()->GetURL("c.com", "/post_message.html")); | |
2166 GURL d_url(embedded_test_server()->GetURL("d.com", "/post_message.html")); | |
2167 NavigateFrameToURL(child0, b_url); | |
2168 EXPECT_TRUE(WaitForRenderFrameReady(child0->current_frame_host())); | |
nasko
2015/05/04 17:16:55
Do we really need those WaitForRenderFrameReady ca
alexmos
2015/05/04 21:18:03
They won't be necessary once we switch TestFrameNa
nasko
2015/05/04 22:02:13
Let's at least add a TODO to remove them once we f
alexmos
2015/05/04 22:12:00
Good idea, done here and in the one other test whe
| |
2169 NavigateFrameToURL(child1, c_url); | |
2170 EXPECT_TRUE(WaitForRenderFrameReady(child1->current_frame_host())); | |
2171 NavigateFrameToURL(child2, d_url); | |
2172 EXPECT_TRUE(WaitForRenderFrameReady(child2->current_frame_host())); | |
2173 | |
2174 EXPECT_EQ( | |
2175 " Site A ------------ proxies for B C D\n" | |
2176 " |--Site B ------- proxies for A C D\n" | |
2177 " |--Site C ------- proxies for A B D\n" | |
2178 " +--Site D ------- proxies for A B C\n" | |
2179 "Where A = http://a.com/\n" | |
2180 " B = http://b.com/\n" | |
2181 " C = http://c.com/\n" | |
2182 " D = http://d.com/", | |
2183 DepictFrameTree(root)); | |
2184 | |
2185 // Check that each subframe sees itself at correct index in parent.frames. | |
2186 bool success = false; | |
2187 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
2188 child0->current_frame_host(), | |
2189 "window.domAutomationController.send(window === parent.frames[0]);", | |
2190 &success)); | |
2191 EXPECT_TRUE(success); | |
2192 success = false; | |
nasko
2015/05/04 17:16:55
nit: Let's put an empty line before this line to h
alexmos
2015/05/04 21:18:03
Done.
| |
2193 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
2194 child1->current_frame_host(), | |
2195 "window.domAutomationController.send(window === parent.frames[1]);", | |
2196 &success)); | |
2197 EXPECT_TRUE(success); | |
2198 success = false; | |
2199 EXPECT_TRUE(ExecuteScriptAndExtractBool( | |
2200 child2->current_frame_host(), | |
2201 "window.domAutomationController.send(window === parent.frames[2]);", | |
2202 &success)); | |
2203 EXPECT_TRUE(success); | |
2204 | |
2205 // Send a postMessage from B to parent.frames[1], which should go to C, and | |
2206 // wait for reply. | |
2207 PostMessageAndWaitForReply(child0, "postToSibling('subframe-msg', 1)", | |
2208 "\"done-1-1-name\""); | |
2209 | |
2210 // Send a postMessage from C to parent.frames[2], which should go to D, and | |
2211 // wait for reply. | |
2212 PostMessageAndWaitForReply(child1, "postToSibling('subframe-msg', 2)", | |
2213 "\"done-1-2-name\""); | |
2214 | |
2215 // Verify the total number of received messages for each subframe. | |
2216 int child0_received_messages = 0; | |
2217 int child1_received_messages = 0; | |
2218 int child2_received_messages = 0; | |
2219 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
2220 child0->current_frame_host(), | |
2221 "window.domAutomationController.send(window.receivedMessages);", | |
2222 &child0_received_messages)); | |
2223 EXPECT_EQ(1, child0_received_messages); | |
2224 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
nasko
2015/05/04 17:16:55
nit: Having empty lines here too will make it a ta
alexmos
2015/05/04 21:18:03
Done.
| |
2225 child1->current_frame_host(), | |
2226 "window.domAutomationController.send(window.receivedMessages);", | |
2227 &child1_received_messages)); | |
2228 EXPECT_EQ(2, child1_received_messages); | |
2229 EXPECT_TRUE(ExecuteScriptAndExtractInt( | |
2230 child2->current_frame_host(), | |
2231 "window.domAutomationController.send(window.receivedMessages);", | |
2232 &child2_received_messages)); | |
2233 EXPECT_EQ(1, child2_received_messages); | |
2234 } | |
2235 | |
2161 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, RFPHDestruction) { | 2236 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, RFPHDestruction) { |
2162 GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); | 2237 GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); |
2163 NavigateToURL(shell(), main_url); | 2238 NavigateToURL(shell(), main_url); |
2164 | 2239 |
2165 // It is safe to obtain the root frame tree node here, as it doesn't change. | 2240 // It is safe to obtain the root frame tree node here, as it doesn't change. |
2166 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | 2241 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
2167 ->GetFrameTree() | 2242 ->GetFrameTree() |
2168 ->root(); | 2243 ->root(); |
2169 | 2244 |
2170 TestNavigationObserver observer(shell()->web_contents()); | 2245 TestNavigationObserver observer(shell()->web_contents()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2212 " |--Site A\n" | 2287 " |--Site A\n" |
2213 " +--Site A\n" | 2288 " +--Site A\n" |
2214 " |--Site A\n" | 2289 " |--Site A\n" |
2215 " +--Site A\n" | 2290 " +--Site A\n" |
2216 " +--Site A\n" | 2291 " +--Site A\n" |
2217 "Where A = http://127.0.0.1/", | 2292 "Where A = http://127.0.0.1/", |
2218 DepictFrameTree(root)); | 2293 DepictFrameTree(root)); |
2219 } | 2294 } |
2220 | 2295 |
2221 } // namespace content | 2296 } // namespace content |
OLD | NEW |