Chromium Code Reviews| Index: apps/saved_files_service_unittest.cc |
| diff --git a/apps/saved_files_service_unittest.cc b/apps/saved_files_service_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c7239721dedc402962657360128a7723b10ad03f |
| --- /dev/null |
| +++ b/apps/saved_files_service_unittest.cc |
| @@ -0,0 +1,238 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <algorithm> |
| + |
| +#include "apps/saved_files_service.h" |
| +#include "base/files/file_path.h" |
| +#include "base/string_number_conversions.h" |
| +#include "base/test/values_test_util.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/extensions/extension_prefs.h" |
| +#include "chrome/browser/extensions/extension_service.h" |
| +#include "chrome/browser/extensions/extension_system.h" |
| +#include "chrome/browser/extensions/test_extension_environment.h" |
| +#include "chrome/common/extensions/extension.h" |
| +#include "chrome/test/base/testing_profile.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +#if !defined(OS_ANDROID) |
| + |
| +#define TRACE_CALL(expression) \ |
| + do { \ |
| + SCOPED_TRACE(#expression); \ |
| + expression; \ |
| + } while (0) |
| + |
| +using apps::SavedFileEntry; |
| +using apps::SavedFilesService; |
| + |
| +namespace { |
| + |
| +std::string GenerateId(int i) { |
| + return base::IntToString(i) + ":filename.ext"; |
| +} |
| + |
| +} // namespace |
| + |
| +class SavedFilesServiceUnitTest : public testing::Test { |
| + protected: |
| + virtual void SetUp() OVERRIDE { |
| + testing::Test::SetUp(); |
| + extension_ = env_.MakeExtension(*base::test::ParseJson( |
| + "{" |
| + " \"app\": {" |
| + " \"background\": {" |
| + " \"scripts\": [\"background.js\"]" |
| + " }" |
| + " }," |
| + " \"permissions\": [" |
| + " {\"fileSystem\": [\"retainFiles\"]}" |
| + " ]" |
| + "}")); |
| + service_ = SavedFilesService::Get(env_.profile()); |
| + path_ = base::FilePath(FILE_PATH_LITERAL("filename.ext")); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + SavedFilesService::ClearMaxSequenceNumberForTest(); |
| + SavedFilesService::ClearLruSizeForTest(); |
| + testing::Test::TearDown(); |
| + } |
| + |
| + // Check that a registered file entry has the correct value. |
| + void CheckSavedFileEntry(int id, int sequence_number) { |
|
koz (OOO until 15th September)
2013/05/23 07:32:22
I think this would be better named CheckEntrySeque
Sam McNally
2013/05/24 00:46:03
Done.
|
| + std::string id_string = GenerateId(id); |
| + SCOPED_TRACE(id_string); |
| + EXPECT_TRUE(service_->IsRegistered(extension_->id(), id_string)); |
| + const SavedFileEntry* entry = |
| + service_->GetFileEntry(extension_->id(), id_string); |
| + ASSERT_TRUE(entry); |
| + EXPECT_EQ(id_string, entry->id); |
| + EXPECT_EQ(path_, entry->path); |
| + EXPECT_TRUE(entry->writable); |
| + EXPECT_EQ(sequence_number, entry->sequence_number); |
| + } |
| + |
| + // Check that a range of registered file entries have the correct values. |
| + void CheckSavedFileEntries(int start, int end) { |
|
koz (OOO until 15th September)
2013/05/23 07:32:22
CheckRangeEnqueuedInOrder()?
Sam McNally
2013/05/24 00:46:03
Done.
|
| + SavedFileEntry entry; |
| + for (int i = start; i < end; i++) { |
| + CheckSavedFileEntry(i, i + 1); |
| + } |
| + } |
|
koz (OOO until 15th September)
2013/05/23 07:32:22
nit: newline
Sam McNally
2013/05/24 00:46:03
Done.
|
| + extensions::TestExtensionEnvironment env_; |
| + const extensions::Extension* extension_; |
| + SavedFilesService* service_; |
| + base::FilePath path_; |
| +}; |
| + |
| +TEST_F(SavedFilesServiceUnitTest, RetainTwoFilesTest) { |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(1), path_, true); |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(2), path_, true); |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(3), path_, true); |
| + |
| + // Test that no entry has a sequence number. |
| + TRACE_CALL(CheckSavedFileEntry(1, 0)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 0)); |
| + TRACE_CALL(CheckSavedFileEntry(3, 0)); |
| + |
| + // Test that only entry #1 has a sequence number. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 1)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 0)); |
| + |
| + // Test that entry #1 has not changed sequence number because it is the most |
| + // recently enqueued entry. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 1)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 0)); |
| + |
| + // Test that entry #1 is unchanged and entry #2 has been assigned the next |
| + // sequence number. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 1)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 2)); |
| + |
| + // Test that both entries #1 and #2 are unchanged because #2 is the most |
| + // recently enqueued entry. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 1)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 2)); |
| + |
| + // Test that entry #1 has been assigned the next sequence number. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 3)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 2)); |
| + TRACE_CALL(CheckSavedFileEntry(3, 0)); |
| + |
| + EXPECT_FALSE(service_->IsRegistered(extension_->id(), "another id")); |
| + SavedFileEntry entry; |
| + EXPECT_FALSE(service_->GetFileEntry(extension_->id(), "another id")); |
| + |
| + // MaybeClearQueue should be a no-op because the app has the |
| + // fileSystem.retainFiles permission. |
| + service_->MaybeClearQueue(extension_); |
| + TRACE_CALL(CheckSavedFileEntry(1, 3)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 2)); |
| + TRACE_CALL(CheckSavedFileEntry(3, 0)); |
| + |
| + // Test that after a clear, retained file entries are unchanged, but file |
| + // entries that have been registered but not retained are no longer |
| + // registered. |
| + service_->Clear(extension_->id()); |
| + TRACE_CALL(CheckSavedFileEntry(1, 3)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 2)); |
| + EXPECT_FALSE(service_->IsRegistered(extension_->id(), GenerateId(3))); |
| +} |
| + |
| +TEST_F(SavedFilesServiceUnitTest, NoRetainFilesPermissionTest) { |
| + extension_ = env_.MakeExtension(*base::test::ParseJson( |
| + "{\"app\": {\"background\": {\"scripts\": [\"background.js\"]}}," |
| + "\"permissions\": [\"fileSystem\"]}")); |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(1), path_, true); |
| + TRACE_CALL(CheckSavedFileEntry(1, 0)); |
| + SavedFileEntry entry; |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(1)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 1)); |
| + EXPECT_FALSE(service_->IsRegistered(extension_->id(), "another id")); |
| + EXPECT_FALSE(service_->GetFileEntry(extension_->id(), "another id")); |
| + |
| + // MaybeClearQueue should clear the queue, since the app does not have the |
| + // "retainFiles" permission. |
| + service_->MaybeClearQueue(extension_); |
| + std::vector<SavedFileEntry> entries = |
| + service_->GetAllFileEntries(extension_->id()); |
| + EXPECT_TRUE(entries.empty()); |
| +} |
| + |
| +TEST_F(SavedFilesServiceUnitTest, EvictionTest) { |
| + SavedFilesService::SetLruSizeForTest(10); |
| + for (int i = 0; i < 10; i++) { |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(i), path_, true); |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(i)); |
| + } |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(10), path_, true); |
| + |
| + // Expect that entries 0 to 9 are in the queue, but 10 is not. |
| + TRACE_CALL(CheckSavedFileEntries(0, 10)); |
| + TRACE_CALL(CheckSavedFileEntry(10, 0)); |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(10)); |
| + |
| + // Expect that entries 1 to 10 are in the queue, but entry 0 is not. |
| + TRACE_CALL(CheckSavedFileEntry(0, 0)); |
| + TRACE_CALL(CheckSavedFileEntries(1, 11)); |
| + |
| + // Check that retained entries are unchanged after a clear. |
| + service_->Clear(extension_->id()); |
| + SavedFileEntry entry; |
| + EXPECT_FALSE(service_->GetFileEntry(extension_->id(), GenerateId(0))); |
| + TRACE_CALL(CheckSavedFileEntries(1, 11)); |
| + |
| + // Expect that entry 2 is now at the back of the queue, and no further entries |
| + // have been evicted. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 12)); |
| + TRACE_CALL(CheckSavedFileEntries(1, 1)); |
| + TRACE_CALL(CheckSavedFileEntries(3, 11)); |
| + |
| + // Check that retained entries are unchanged after a clear. |
| + service_->Clear(extension_->id()); |
| + TRACE_CALL(CheckSavedFileEntry(2, 12)); |
| + TRACE_CALL(CheckSavedFileEntries(1, 1)); |
| + TRACE_CALL(CheckSavedFileEntries(3, 11)); |
| +} |
| + |
| +TEST_F(SavedFilesServiceUnitTest, SequenceNumberCompactionTest) { |
|
koz (OOO until 15th September)
2013/05/23 07:32:22
Just wanted to say, these tests are awesome!
|
| + SavedFilesService::SetMaxSequenceNumberForTest(8); |
| + SavedFilesService::SetLruSizeForTest(8); |
| + for (int i = 0; i < 4; i++) { |
| + service_->RegisterFileEntry(extension_->id(), GenerateId(i), path_, true); |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(i)); |
| + } |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(3)); |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(2)); |
| + |
| + // The sequence numbers should be sparse, as they have not gone over the |
| + // limit. |
| + TRACE_CALL(CheckSavedFileEntry(0, 1)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 2)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 7)); |
| + TRACE_CALL(CheckSavedFileEntry(3, 6)); |
| + service_->Clear(extension_->id()); |
| + TRACE_CALL(CheckSavedFileEntry(0, 1)); |
| + TRACE_CALL(CheckSavedFileEntry(1, 2)); |
| + TRACE_CALL(CheckSavedFileEntry(2, 7)); |
| + TRACE_CALL(CheckSavedFileEntry(3, 6)); |
| + |
| + // This should push the sequence number to the limit of 8, and trigger a |
| + // sequence number compaction. Expect that the sequence numbers are |
| + // contiguous from 1 to 4. |
| + service_->EnqueueFileEntry(extension_->id(), GenerateId(3)); |
| + TRACE_CALL(CheckSavedFileEntries(0, 4)); |
| + service_->Clear(extension_->id()); |
| + TRACE_CALL(CheckSavedFileEntries(0, 4)); |
| +} |
| +#endif |