OLD | NEW |
(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 "base/time/time.h" |
| 8 #include "content/public/test/test_browser_thread_bundle.h" |
| 9 #include "extensions/browser/extension_api_frame_id_map.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 using FrameIdCallback = extensions::ExtensionApiFrameIdMap::FrameIdCallback; |
| 13 |
| 14 namespace extensions { |
| 15 |
| 16 namespace { |
| 17 |
| 18 ExtensionApiFrameId ToTestFrameId(int render_process_id, int frame_routing_id) { |
| 19 if (render_process_id == -1 && frame_routing_id == -1) |
| 20 return ExtensionApiFrameId(); |
| 21 // Return a deterministic value (yet different from the input) for testing. |
| 22 return ExtensionApiFrameId(render_process_id + 1, frame_routing_id + 1); |
| 23 } |
| 24 |
| 25 class TestExtensionApiFrameIdMap : public ExtensionApiFrameIdMap { |
| 26 public: |
| 27 int GetInternalSize() { return frame_id_map_.size(); } |
| 28 int GetInternalCallbackCount() { return callbacks_.size(); } |
| 29 void TriggerInternalCleanup() { |
| 30 // Modify the internal structure: Set the creation time to a time in the |
| 31 // distant past and trigger a removal. |
| 32 for (FrameIdRemovalTask& task : pending_deletions_) |
| 33 task.creation_time = base::TimeTicks(); |
| 34 // The map cannot have invalid frame IDs, so this is a no-op. |
| 35 RemoveFrameId(-1, -1); |
| 36 // The only remaining task is the removal of the invalid ID above, all other |
| 37 // pending deletion tasks should have been run by now. |
| 38 EXPECT_EQ(1u, pending_deletions_.size()); |
| 39 } |
| 40 |
| 41 private: |
| 42 // ExtensionApiFrameIdMap: |
| 43 ExtensionApiFrameId KeyToValue(const RenderFrameIdKey& key) const override { |
| 44 return ToTestFrameId(key.render_process_id, key.frame_routing_id); |
| 45 } |
| 46 }; |
| 47 |
| 48 class ExtensionApiFrameIdMapTest : public testing::Test { |
| 49 public: |
| 50 ExtensionApiFrameIdMapTest() |
| 51 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} |
| 52 |
| 53 FrameIdCallback CreateCallback(int render_process_id, int frame_routing_id) { |
| 54 return base::Bind(&ExtensionApiFrameIdMapTest::OnCalledCallback, |
| 55 base::Unretained(this), render_process_id, |
| 56 frame_routing_id); |
| 57 } |
| 58 |
| 59 void OnCalledCallback(int render_process_id, |
| 60 int frame_routing_id, |
| 61 const ExtensionApiFrameId extension_api_frame_id) { |
| 62 // Save results for later, to see whether the ordering is OK. |
| 63 results_.push_back(extension_api_frame_id); |
| 64 |
| 65 // If this fails, then the mapping is completely wrong. |
| 66 EXPECT_EQ(ToTestFrameId(render_process_id, frame_routing_id), |
| 67 extension_api_frame_id); |
| 68 } |
| 69 |
| 70 const std::vector<ExtensionApiFrameId>& results() { return results_; } |
| 71 |
| 72 private: |
| 73 content::TestBrowserThreadBundle thread_bundle_; |
| 74 std::vector<ExtensionApiFrameId> results_; |
| 75 |
| 76 DISALLOW_COPY_AND_ASSIGN(ExtensionApiFrameIdMapTest); |
| 77 }; |
| 78 |
| 79 } // namespace |
| 80 |
| 81 // Tests whether getting data from the map gives consistent results. |
| 82 TEST_F(ExtensionApiFrameIdMapTest, Basics) { |
| 83 TestExtensionApiFrameIdMap map; |
| 84 EXPECT_EQ(0, map.GetInternalSize()); |
| 85 |
| 86 EXPECT_EQ(ToTestFrameId(1, 2), map.GetFrameId(1, 2)); |
| 87 EXPECT_EQ(1, map.GetInternalSize()); |
| 88 |
| 89 // Already cached, the map size should not change. |
| 90 EXPECT_EQ(ToTestFrameId(1, 2), map.GetFrameId(1, 2)); |
| 91 EXPECT_EQ(1, map.GetInternalSize()); |
| 92 |
| 93 EXPECT_EQ(ToTestFrameId(2, 1), map.GetFrameId(2, 1)); |
| 94 EXPECT_EQ(2, map.GetInternalSize()); |
| 95 |
| 96 // Don't save invalid values in the map because they are never deleted. |
| 97 EXPECT_EQ(ToTestFrameId(-1, -1), map.GetFrameId(-1, -1)); |
| 98 EXPECT_EQ(2, map.GetInternalSize()); |
| 99 |
| 100 // Remove frame ID. Key erasure is not immediate but delayed. |
| 101 map.RemoveFrameId(1, 2); |
| 102 EXPECT_EQ(2, map.GetInternalSize()); |
| 103 map.TriggerInternalCleanup(); |
| 104 EXPECT_EQ(1, map.GetInternalSize()); |
| 105 |
| 106 // Non-existing frame ID. |
| 107 map.RemoveFrameId(1, 1337); |
| 108 EXPECT_EQ(1, map.GetInternalSize()); |
| 109 map.TriggerInternalCleanup(); |
| 110 EXPECT_EQ(1, map.GetInternalSize()); |
| 111 |
| 112 // Non-existing frame ID (because it's already removed). |
| 113 map.RemoveFrameId(1, 2); |
| 114 EXPECT_EQ(1, map.GetInternalSize()); |
| 115 map.TriggerInternalCleanup(); |
| 116 EXPECT_EQ(1, map.GetInternalSize()); |
| 117 |
| 118 // Invalid frame ID. |
| 119 map.RemoveFrameId(-1, -1); |
| 120 EXPECT_EQ(1, map.GetInternalSize()); |
| 121 map.TriggerInternalCleanup(); |
| 122 EXPECT_EQ(1, map.GetInternalSize()); |
| 123 } |
| 124 |
| 125 TEST_F(ExtensionApiFrameIdMapTest, GetFrameIdOnIO) { |
| 126 TestExtensionApiFrameIdMap map; |
| 127 EXPECT_EQ(0, map.GetInternalSize()); |
| 128 |
| 129 // Two identical calls, should be processed at the next message loop. |
| 130 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2)); |
| 131 EXPECT_EQ(1, map.GetInternalCallbackCount()); |
| 132 EXPECT_EQ(0, map.GetInternalSize()); |
| 133 |
| 134 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2)); |
| 135 EXPECT_EQ(2, map.GetInternalCallbackCount()); |
| 136 EXPECT_EQ(0, map.GetInternalSize()); |
| 137 |
| 138 // First get the frame ID on IO (queued on message loop), then on UI. |
| 139 map.GetFrameIdOnIO(2, 1, CreateCallback(2, 1)); |
| 140 EXPECT_EQ(3, map.GetInternalCallbackCount()); |
| 141 EXPECT_EQ(0, map.GetInternalSize()); |
| 142 |
| 143 EXPECT_EQ(ToTestFrameId(2, 1), map.GetFrameId(2, 1)); |
| 144 EXPECT_EQ(1, map.GetInternalSize()); |
| 145 |
| 146 // First get the frame ID on UI, then on IO (queued on message loop). |
| 147 EXPECT_EQ(ToTestFrameId(3, 1), map.GetFrameId(3, 1)); |
| 148 EXPECT_EQ(2, map.GetInternalSize()); |
| 149 |
| 150 map.GetFrameIdOnIO(3, 1, CreateCallback(3, 1)); |
| 151 EXPECT_EQ(4, map.GetInternalCallbackCount()); |
| 152 EXPECT_EQ(2, map.GetInternalSize()); |
| 153 |
| 154 // A call identical to the very first call. |
| 155 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2)); |
| 156 EXPECT_EQ(5, map.GetInternalCallbackCount()); |
| 157 EXPECT_EQ(2, map.GetInternalSize()); |
| 158 |
| 159 base::RunLoop().RunUntilIdle(); |
| 160 EXPECT_EQ(0, map.GetInternalCallbackCount()); |
| 161 |
| 162 EXPECT_EQ(3, map.GetInternalSize()); |
| 163 ASSERT_EQ(5U, results().size()); |
| 164 |
| 165 // Callbacks should be run in order. |
| 166 EXPECT_EQ(ToTestFrameId(1, 2), results()[0]); |
| 167 EXPECT_EQ(ToTestFrameId(1, 2), results()[1]); |
| 168 EXPECT_EQ(ToTestFrameId(2, 1), results()[2]); |
| 169 EXPECT_EQ(ToTestFrameId(3, 1), results()[3]); |
| 170 EXPECT_EQ(ToTestFrameId(1, 2), results()[4]); |
| 171 |
| 172 // Request the frame ID for input that was already looked up. Should complete |
| 173 // synchronously. |
| 174 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2)); |
| 175 EXPECT_EQ(0, map.GetInternalCallbackCount()); |
| 176 EXPECT_EQ(3, map.GetInternalSize()); |
| 177 ASSERT_EQ(6U, results().size()); |
| 178 EXPECT_EQ(ToTestFrameId(1, 2), results()[5]); |
| 179 |
| 180 // Queue frame removal and look up frame ID. Frame ID should not be removed |
| 181 // yet and GetFrameIdOnIO() should complete synchronously. |
| 182 map.RemoveFrameId(1, 2); |
| 183 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2)); |
| 184 EXPECT_EQ(0, map.GetInternalCallbackCount()); |
| 185 EXPECT_EQ(3, map.GetInternalSize()); |
| 186 ASSERT_EQ(7U, results().size()); |
| 187 EXPECT_EQ(ToTestFrameId(1, 2), results()[6]); |
| 188 |
| 189 // Now fire the timer that triggers frame removal, and request the frame ID. |
| 190 // Thread hopping should be necessary again. |
| 191 map.TriggerInternalCleanup(); |
| 192 EXPECT_EQ(2, map.GetInternalSize()); |
| 193 map.GetFrameIdOnIO(1, 2, CreateCallback(1, 2)); |
| 194 EXPECT_EQ(1, map.GetInternalCallbackCount()); |
| 195 base::RunLoop().RunUntilIdle(); |
| 196 EXPECT_EQ(0, map.GetInternalCallbackCount()); |
| 197 EXPECT_EQ(3, map.GetInternalSize()); |
| 198 ASSERT_EQ(8U, results().size()); |
| 199 EXPECT_EQ(ToTestFrameId(1, 2), results()[7]); |
| 200 } |
| 201 |
| 202 } // namespace extensions |
OLD | NEW |