OLD | NEW |
(Empty) | |
| 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 <algorithm> |
| 6 |
| 7 #include "apps/saved_files_service.h" |
| 8 #include "base/files/file_path.h" |
| 9 #include "base/string_number_conversions.h" |
| 10 #include "base/test/values_test_util.h" |
| 11 #include "base/values.h" |
| 12 #include "chrome/browser/extensions/extension_prefs.h" |
| 13 #include "chrome/browser/extensions/extension_service.h" |
| 14 #include "chrome/browser/extensions/extension_system.h" |
| 15 #include "chrome/browser/extensions/test_extension_environment.h" |
| 16 #include "chrome/common/extensions/extension.h" |
| 17 #include "chrome/test/base/testing_profile.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 #if !defined(OS_ANDROID) |
| 21 |
| 22 #define TRACE_CALL(expression) \ |
| 23 do { \ |
| 24 SCOPED_TRACE(#expression); \ |
| 25 expression; \ |
| 26 } while (0) |
| 27 |
| 28 using apps::SavedFileEntry; |
| 29 using apps::SavedFilesService; |
| 30 |
| 31 namespace { |
| 32 |
| 33 std::string GenerateId(int i) { |
| 34 return base::IntToString(i) + ":filename.ext"; |
| 35 } |
| 36 |
| 37 } // namespace |
| 38 |
| 39 class SavedFilesServiceUnitTest : public testing::Test { |
| 40 protected: |
| 41 virtual void SetUp() OVERRIDE { |
| 42 testing::Test::SetUp(); |
| 43 extension_ = env_.MakeExtension(*base::test::ParseJson( |
| 44 "{" |
| 45 " \"app\": {" |
| 46 " \"background\": {" |
| 47 " \"scripts\": [\"background.js\"]" |
| 48 " }" |
| 49 " }," |
| 50 " \"permissions\": [" |
| 51 " {\"fileSystem\": [\"retainFiles\"]}" |
| 52 " ]" |
| 53 "}")); |
| 54 service_ = SavedFilesService::Get(env_.profile()); |
| 55 path_ = base::FilePath(FILE_PATH_LITERAL("filename.ext")); |
| 56 } |
| 57 |
| 58 virtual void TearDown() OVERRIDE { |
| 59 SavedFilesService::ClearMaxSequenceNumberForTest(); |
| 60 SavedFilesService::ClearLruSizeForTest(); |
| 61 testing::Test::TearDown(); |
| 62 } |
| 63 |
| 64 // Check that a registered file entry has the correct value. |
| 65 void CheckEntrySequenceNumber(int id, int sequence_number) { |
| 66 std::string id_string = GenerateId(id); |
| 67 SCOPED_TRACE(id_string); |
| 68 EXPECT_TRUE(service_->IsRegistered(extension_->id(), id_string)); |
| 69 const SavedFileEntry* entry = |
| 70 service_->GetFileEntry(extension_->id(), id_string); |
| 71 ASSERT_TRUE(entry); |
| 72 EXPECT_EQ(id_string, entry->id); |
| 73 EXPECT_EQ(path_, entry->path); |
| 74 EXPECT_TRUE(entry->writable); |
| 75 EXPECT_EQ(sequence_number, entry->sequence_number); |
| 76 } |
| 77 |
| 78 // Check that a range of registered file entries have the correct values. |
| 79 void CheckRangeEnqueuedInOrder(int start, int end) { |
| 80 SavedFileEntry entry; |
| 81 for (int i = start; i < end; i++) { |
| 82 CheckEntrySequenceNumber(i, i + 1); |
| 83 } |
| 84 } |
| 85 |
| 86 extensions::TestExtensionEnvironment env_; |
| 87 const extensions::Extension* extension_; |
| 88 SavedFilesService* service_; |
| 89 base::FilePath path_; |
| 90 }; |
| 91 |
| 92 TEST_F(SavedFilesServiceUnitTest, RetainTwoFilesTest) { |
| 93 service_->RegisterFileEntry(extension_->id(), GenerateId(1), path_, true); |
| 94 service_->RegisterFileEntry(extension_->id(), GenerateId(2), path_, true); |
| 95 service_->RegisterFileEntry(extension_->id(), GenerateId(3), path_, true); |
| 96 |
| 97 // Test that no entry has a sequence number. |
| 98 TRACE_CALL(CheckEntrySequenceNumber(1, 0)); |
| 99 TRACE_CALL(CheckEntrySequenceNumber(2, 0)); |
| 100 TRACE_CALL(CheckEntrySequenceNumber(3, 0)); |
| 101 |
| 102 // Test that only entry #1 has a sequence number. |
| 103 service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| 104 TRACE_CALL(CheckEntrySequenceNumber(1, 1)); |
| 105 TRACE_CALL(CheckEntrySequenceNumber(2, 0)); |
| 106 |
| 107 // Test that entry #1 has not changed sequence number because it is the most |
| 108 // recently enqueued entry. |
| 109 service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| 110 TRACE_CALL(CheckEntrySequenceNumber(1, 1)); |
| 111 TRACE_CALL(CheckEntrySequenceNumber(2, 0)); |
| 112 |
| 113 // Test that entry #1 is unchanged and entry #2 has been assigned the next |
| 114 // sequence number. |
| 115 service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| 116 TRACE_CALL(CheckEntrySequenceNumber(1, 1)); |
| 117 TRACE_CALL(CheckEntrySequenceNumber(2, 2)); |
| 118 |
| 119 // Test that both entries #1 and #2 are unchanged because #2 is the most |
| 120 // recently enqueued entry. |
| 121 service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| 122 TRACE_CALL(CheckEntrySequenceNumber(1, 1)); |
| 123 TRACE_CALL(CheckEntrySequenceNumber(2, 2)); |
| 124 |
| 125 // Test that entry #1 has been assigned the next sequence number. |
| 126 service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| 127 TRACE_CALL(CheckEntrySequenceNumber(1, 3)); |
| 128 TRACE_CALL(CheckEntrySequenceNumber(2, 2)); |
| 129 TRACE_CALL(CheckEntrySequenceNumber(3, 0)); |
| 130 |
| 131 EXPECT_FALSE(service_->IsRegistered(extension_->id(), "another id")); |
| 132 SavedFileEntry entry; |
| 133 EXPECT_FALSE(service_->GetFileEntry(extension_->id(), "another id")); |
| 134 |
| 135 // ClearQueueIfNoRetainPermission should be a no-op because the app has the |
| 136 // fileSystem.retainFiles permission. |
| 137 service_->ClearQueueIfNoRetainPermission(extension_); |
| 138 TRACE_CALL(CheckEntrySequenceNumber(1, 3)); |
| 139 TRACE_CALL(CheckEntrySequenceNumber(2, 2)); |
| 140 TRACE_CALL(CheckEntrySequenceNumber(3, 0)); |
| 141 |
| 142 // Test that after a clear, retained file entries are unchanged, but file |
| 143 // entries that have been registered but not retained are no longer |
| 144 // registered. |
| 145 service_->Clear(extension_->id()); |
| 146 TRACE_CALL(CheckEntrySequenceNumber(1, 3)); |
| 147 TRACE_CALL(CheckEntrySequenceNumber(2, 2)); |
| 148 EXPECT_FALSE(service_->IsRegistered(extension_->id(), GenerateId(3))); |
| 149 } |
| 150 |
| 151 TEST_F(SavedFilesServiceUnitTest, NoRetainFilesPermissionTest) { |
| 152 extension_ = env_.MakeExtension(*base::test::ParseJson( |
| 153 "{\"app\": {\"background\": {\"scripts\": [\"background.js\"]}}," |
| 154 "\"permissions\": [\"fileSystem\"]}")); |
| 155 service_->RegisterFileEntry(extension_->id(), GenerateId(1), path_, true); |
| 156 TRACE_CALL(CheckEntrySequenceNumber(1, 0)); |
| 157 SavedFileEntry entry; |
| 158 service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| 159 TRACE_CALL(CheckEntrySequenceNumber(1, 1)); |
| 160 EXPECT_FALSE(service_->IsRegistered(extension_->id(), "another id")); |
| 161 EXPECT_FALSE(service_->GetFileEntry(extension_->id(), "another id")); |
| 162 |
| 163 // ClearQueueIfNoRetainPermission should clear the queue, since the app does |
| 164 // not have the "retainFiles" permission. |
| 165 service_->ClearQueueIfNoRetainPermission(extension_); |
| 166 std::vector<SavedFileEntry> entries = |
| 167 service_->GetAllFileEntries(extension_->id()); |
| 168 EXPECT_TRUE(entries.empty()); |
| 169 } |
| 170 |
| 171 TEST_F(SavedFilesServiceUnitTest, EvictionTest) { |
| 172 SavedFilesService::SetLruSizeForTest(10); |
| 173 for (int i = 0; i < 10; i++) { |
| 174 service_->RegisterFileEntry(extension_->id(), GenerateId(i), path_, true); |
| 175 service_->EnqueueFileEntry(extension_->id(), GenerateId(i)); |
| 176 } |
| 177 service_->RegisterFileEntry(extension_->id(), GenerateId(10), path_, true); |
| 178 |
| 179 // Expect that entries 0 to 9 are in the queue, but 10 is not. |
| 180 TRACE_CALL(CheckRangeEnqueuedInOrder(0, 10)); |
| 181 TRACE_CALL(CheckEntrySequenceNumber(10, 0)); |
| 182 service_->EnqueueFileEntry(extension_->id(), GenerateId(10)); |
| 183 |
| 184 // Expect that entries 1 to 10 are in the queue, but entry 0 is not. |
| 185 TRACE_CALL(CheckEntrySequenceNumber(0, 0)); |
| 186 TRACE_CALL(CheckRangeEnqueuedInOrder(1, 11)); |
| 187 |
| 188 // Check that retained entries are unchanged after a clear. |
| 189 service_->Clear(extension_->id()); |
| 190 SavedFileEntry entry; |
| 191 EXPECT_FALSE(service_->GetFileEntry(extension_->id(), GenerateId(0))); |
| 192 TRACE_CALL(CheckRangeEnqueuedInOrder(1, 11)); |
| 193 |
| 194 // Expect that entry 2 is now at the back of the queue, and no further entries |
| 195 // have been evicted. |
| 196 service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| 197 TRACE_CALL(CheckEntrySequenceNumber(2, 12)); |
| 198 TRACE_CALL(CheckRangeEnqueuedInOrder(1, 1)); |
| 199 TRACE_CALL(CheckRangeEnqueuedInOrder(3, 11)); |
| 200 |
| 201 // Check that retained entries are unchanged after a clear. |
| 202 service_->Clear(extension_->id()); |
| 203 TRACE_CALL(CheckEntrySequenceNumber(2, 12)); |
| 204 TRACE_CALL(CheckRangeEnqueuedInOrder(1, 1)); |
| 205 TRACE_CALL(CheckRangeEnqueuedInOrder(3, 11)); |
| 206 } |
| 207 |
| 208 TEST_F(SavedFilesServiceUnitTest, SequenceNumberCompactionTest) { |
| 209 SavedFilesService::SetMaxSequenceNumberForTest(8); |
| 210 SavedFilesService::SetLruSizeForTest(8); |
| 211 for (int i = 0; i < 4; i++) { |
| 212 service_->RegisterFileEntry(extension_->id(), GenerateId(i), path_, true); |
| 213 service_->EnqueueFileEntry(extension_->id(), GenerateId(i)); |
| 214 } |
| 215 service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| 216 service_->EnqueueFileEntry(extension_->id(), GenerateId(3)); |
| 217 service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| 218 |
| 219 // The sequence numbers should be sparse, as they have not gone over the |
| 220 // limit. |
| 221 TRACE_CALL(CheckEntrySequenceNumber(0, 1)); |
| 222 TRACE_CALL(CheckEntrySequenceNumber(1, 2)); |
| 223 TRACE_CALL(CheckEntrySequenceNumber(2, 7)); |
| 224 TRACE_CALL(CheckEntrySequenceNumber(3, 6)); |
| 225 service_->Clear(extension_->id()); |
| 226 TRACE_CALL(CheckEntrySequenceNumber(0, 1)); |
| 227 TRACE_CALL(CheckEntrySequenceNumber(1, 2)); |
| 228 TRACE_CALL(CheckEntrySequenceNumber(2, 7)); |
| 229 TRACE_CALL(CheckEntrySequenceNumber(3, 6)); |
| 230 |
| 231 // This should push the sequence number to the limit of 8, and trigger a |
| 232 // sequence number compaction. Expect that the sequence numbers are |
| 233 // contiguous from 1 to 4. |
| 234 service_->EnqueueFileEntry(extension_->id(), GenerateId(3)); |
| 235 TRACE_CALL(CheckRangeEnqueuedInOrder(0, 4)); |
| 236 service_->Clear(extension_->id()); |
| 237 TRACE_CALL(CheckRangeEnqueuedInOrder(0, 4)); |
| 238 } |
| 239 #endif |
OLD | NEW |