Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: extensions/browser/extension_api_frame_id_map_unittest.cc

Issue 1413543005: Use FrameTreeNode ID as frameId in extension APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: s/runs/that runs/ + public copy cons. to avoid compiler error Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "base/bind.h"
6 #include "base/run_loop.h"
7 #include "content/public/test/test_browser_thread_bundle.h"
8 #include "extensions/browser/extension_api_frame_id_map.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 using FrameIdCallback = extensions::ExtensionApiFrameIdMap::FrameIdCallback;
12
13 namespace extensions {
14
15 namespace {
16
17 int ToTestFrameId(int render_process_id, int frame_routing_id) {
18 if (render_process_id == -1 && frame_routing_id == -1)
19 return ExtensionApiFrameIdMap::kInvalidFrameId;
20 // Return a deterministic value (yet different from the input) for testing.
21 // To make debugging easier: Ending with 0 = frame ID.
22 return render_process_id * 1000 + frame_routing_id * 10;
23 }
24
25 int ToTestParentFrameId(int render_process_id, int frame_routing_id) {
26 if (render_process_id == -1 && frame_routing_id == -1)
27 return ExtensionApiFrameIdMap::kInvalidFrameId;
28 // Return a deterministic value (yet different from the input) for testing.
29 // To make debugging easier: Ending with 7 = parent frame ID.
30 return render_process_id * 1000 + frame_routing_id * 10 + 7;
31 }
32
33 class TestExtensionApiFrameIdMap : public ExtensionApiFrameIdMap {
34 public:
35 int GetInternalSize() { return frame_id_map_.size(); }
36 int GetInternalCallbackCount() {
37 int count = 0;
38 for (auto& it : callbacks_map_)
39 count += it.second.callbacks.size();
40 return count;
41 }
42
43 // These indirections are necessary because we cannot mock RenderFrameHost
44 // in unit tests :(
nasko 2016/01/05 00:39:58 You technically can. Using TestRenderFrameHost and
robwu 2016/01/05 10:59:03 Those are not in the public part of content/, incl
nasko 2016/01/06 17:19:38 The harness is public: content/public/test/test_re
robwu 2016/01/06 17:48:59 Thanks for this pointer, that could work indeed. I
45 void SetInternalFrameId(int render_process_id, int frame_routing_id) {
46 CacheFrameId(RenderFrameIdKey(render_process_id, frame_routing_id));
47 }
48 void RemoveInternalFrameId(int render_process_id, int frame_routing_id) {
49 RemoveFrameId(RenderFrameIdKey(render_process_id, frame_routing_id));
50 }
51
52 private:
53 // ExtensionApiFrameIdMap:
54 CachedFrameIdPair KeyToValue(const RenderFrameIdKey& key) const override {
55 return CachedFrameIdPair(
56 ToTestFrameId(key.render_process_id, key.frame_routing_id),
57 ToTestParentFrameId(key.render_process_id, key.frame_routing_id));
58 }
59 };
60
61 class ExtensionApiFrameIdMapTest : public testing::Test {
62 public:
63 ExtensionApiFrameIdMapTest()
64 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
65
66 FrameIdCallback CreateCallback(int render_process_id,
67 int frame_routing_id,
68 const std::string& callback_name_for_testing) {
69 return base::Bind(&ExtensionApiFrameIdMapTest::OnCalledCallback,
70 base::Unretained(this), render_process_id,
71 frame_routing_id, callback_name_for_testing);
72 }
73
74 void OnCalledCallback(int render_process_id,
75 int frame_routing_id,
76 const std::string& callback_name_for_testing,
77 int extension_api_frame_id,
78 int extension_api_parent_frame_id) {
79 results_.push_back(callback_name_for_testing);
80
81 // If this fails, then the mapping is completely wrong.
82 EXPECT_EQ(ToTestFrameId(render_process_id, frame_routing_id),
83 extension_api_frame_id);
84 EXPECT_EQ(ToTestParentFrameId(render_process_id, frame_routing_id),
85 extension_api_parent_frame_id);
86 }
87
88 const std::vector<std::string>& results() { return results_; }
89 void ClearResults() { results_.clear(); }
90
91 private:
92 content::TestBrowserThreadBundle thread_bundle_;
93 // Used to verify the order of callbacks.
94 std::vector<std::string> results_;
95
96 DISALLOW_COPY_AND_ASSIGN(ExtensionApiFrameIdMapTest);
97 };
98
99 } // namespace
100
101 TEST_F(ExtensionApiFrameIdMapTest, GetFrameIdOnIO) {
102 TestExtensionApiFrameIdMap map;
103 EXPECT_EQ(0, map.GetInternalSize());
104
105 // Two identical calls, should be processed at the next message loop.
106 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2, "first"));
107 EXPECT_EQ(1, map.GetInternalCallbackCount());
108 EXPECT_EQ(0, map.GetInternalSize());
109
110 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2, "first again"));
111 EXPECT_EQ(2, map.GetInternalCallbackCount());
112 EXPECT_EQ(0, map.GetInternalSize());
113
114 // First get the frame ID on IO (queued on message loop), then set it on UI.
115 // No callbacks should be invoked because the IO thread cannot know that the
116 // frame ID was set on the UI thread.
117 map.GetFrameIdOnIO(2, 1, CreateCallback(2, 1, "something else"));
118 EXPECT_EQ(3, map.GetInternalCallbackCount());
119 EXPECT_EQ(0, map.GetInternalSize());
120
121 map.SetInternalFrameId(2, 1);
122 EXPECT_EQ(1, map.GetInternalSize());
123 EXPECT_EQ(0U, results().size());
124
125 // Run some self-contained test. They should not affect the above callbacks.
126 {
127 // First set the frame ID on UI, then get it on IO. Callback should
128 // immediately be invoked.
129 map.SetInternalFrameId(3, 1);
130 EXPECT_EQ(2, map.GetInternalSize());
131
132 map.GetFrameIdOnIO(3, 1, CreateCallback(3, 1, "the only result"));
133 EXPECT_EQ(3, map.GetInternalCallbackCount()); // No change.
134 EXPECT_EQ(2, map.GetInternalSize()); // +1
135 ASSERT_EQ(1U, results().size()); // +1
136 EXPECT_EQ("the only result", results()[0]);
137 ClearResults();
138 }
139
140 {
141 // Request the frame ID on IO, set the frame ID (in reality, set on the UI),
142 // and request another frame ID. The last query should cause both callbacks
143 // to run because the frame ID is known at the time of the call.
144 map.GetFrameIdOnIO(7, 2, CreateCallback(7, 2, "queued"));
145 EXPECT_EQ(4, map.GetInternalCallbackCount()); // +1
146
147 map.SetInternalFrameId(7, 2);
148 EXPECT_EQ(3, map.GetInternalSize()); // +1
149
150 map.GetFrameIdOnIO(7, 2, CreateCallback(7, 2, "not queued"));
151 EXPECT_EQ(3, map.GetInternalCallbackCount()); // -1 (first callback ran).
152 EXPECT_EQ(3, map.GetInternalSize()); // No change.
153 ASSERT_EQ(2U, results().size()); // +2 (both callbacks ran).
154 EXPECT_EQ("queued", results()[0]);
155 EXPECT_EQ("not queued", results()[1]);
156 ClearResults();
157 }
158
159 // A call identical to the very first call.
160 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2, "same as first"));
161 EXPECT_EQ(4, map.GetInternalCallbackCount());
162 EXPECT_EQ(3, map.GetInternalSize());
163
164 // Trigger the queued callbacks.
165 base::RunLoop().RunUntilIdle();
166 EXPECT_EQ(0, map.GetInternalCallbackCount()); // -4 (no queued callbacks).
167
168 EXPECT_EQ(4, map.GetInternalSize()); // +1 (1 new cached frame ID).
169 ASSERT_EQ(4U, results().size()); // +4 (callbacks ran).
170
171 // PostTasks are processed in order, so the very first callbacks should be
172 // processed. As soon as the first callback is available, all of its callbacks
173 // should be run (no deferrals!).
174 EXPECT_EQ("first", results()[0]);
175 EXPECT_EQ("first again", results()[1]);
176 EXPECT_EQ("same as first", results()[2]);
177 // This was queued after "first again", but has a different frame ID, so it
178 // is received after "same as first".
179 EXPECT_EQ("something else", results()[3]);
180 ClearResults();
181
182 // Request the frame ID for input that was already looked up. Should complete
183 // synchronously.
184 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2, "first and cached"));
185 EXPECT_EQ(0, map.GetInternalCallbackCount()); // No change.
186 EXPECT_EQ(4, map.GetInternalSize()); // No change.
187 ASSERT_EQ(1U, results().size()); // +1 (synchronous callback).
188 EXPECT_EQ("first and cached", results()[0]);
189 ClearResults();
190
191 // Trigger frame removal and look up frame ID. The frame ID should no longer
192 // be available. and GetFrameIdOnIO() should require a thread hop.
193 map.RemoveInternalFrameId(1, 2);
194 EXPECT_EQ(3, map.GetInternalSize()); // -1
195 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2, "first was removed"));
196 EXPECT_EQ(1, map.GetInternalCallbackCount()); // +1
197 ASSERT_EQ(0U, results().size()); // No change (queued callback).
198 base::RunLoop().RunUntilIdle();
199 EXPECT_EQ(0, map.GetInternalCallbackCount()); // -1 (callback not in queue).
200 EXPECT_EQ(4, map.GetInternalSize()); // +1 (cached frame ID).
201 ASSERT_EQ(1U, results().size()); // +1 (callback ran).
202 EXPECT_EQ("first was removed", results()[0]);
203 }
204
205 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698