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