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