OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/notifications/notification_database.h" | 5 #include "content/browser/notifications/notification_database.h" |
6 | 6 |
7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 #include "third_party/leveldatabase/src/include/leveldb/db.h" | |
10 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | |
9 | 11 |
10 namespace content { | 12 namespace content { |
11 | 13 |
12 class NotificationDatabaseTest : public ::testing::Test { | 14 class NotificationDatabaseTest : public ::testing::Test { |
13 protected: | 15 protected: |
14 // Creates a new NotificationDatabase instance in memory. | 16 // Creates a new NotificationDatabase instance in memory. |
15 NotificationDatabase* CreateDatabaseInMemory() { | 17 NotificationDatabase* CreateDatabaseInMemory() { |
16 return new NotificationDatabase(base::FilePath()); | 18 return new NotificationDatabase(base::FilePath()); |
17 } | 19 } |
18 | 20 |
19 // Creates a new NotificationDatabase instance in |path|. | 21 // Creates a new NotificationDatabase instance in |path|. |
20 NotificationDatabase* CreateDatabaseOnFileSystem( | 22 NotificationDatabase* CreateDatabaseOnFileSystem( |
21 const base::FilePath& path) { | 23 const base::FilePath& path) { |
22 return new NotificationDatabase(path); | 24 return new NotificationDatabase(path); |
23 } | 25 } |
24 | 26 |
25 // Returns if |database| has been opened. | 27 // Returns if |database| has been opened. |
26 bool IsDatabaseOpen(NotificationDatabase* database) { | 28 bool IsDatabaseOpen(NotificationDatabase* database) { |
27 return database->IsOpen(); | 29 return database->IsOpen(); |
28 } | 30 } |
29 | 31 |
30 // Returns if |database| is an in-memory only database. | 32 // Returns if |database| is an in-memory only database. |
31 bool IsInMemoryDatabase(NotificationDatabase* database) { | 33 bool IsInMemoryDatabase(NotificationDatabase* database) { |
32 return database->IsInMemoryDatabase(); | 34 return database->IsInMemoryDatabase(); |
33 } | 35 } |
36 | |
37 // Writes a LevelDB key-value pair directly to the LevelDB backing the | |
38 // notification database in |database|. Returns whether the pair could | |
39 // be written to the database successfully. | |
40 bool WriteLevelDBKeyValuePair(NotificationDatabase* database, | |
41 const std::string& key, | |
42 const std::string& value) { | |
43 leveldb::Status status = database->db()->Put(leveldb::WriteOptions(), | |
44 key, value); | |
45 if (status.ok()) | |
Bernhard Bauer
2015/03/11 22:02:38
Change the return type to void and ASSERT? You can
Peter Beverloo
2015/03/11 22:33:33
ASSERT_NO_FATAL_FAILURE! Awesome! Changed :-).
| |
46 return true; | |
47 | |
48 LOG(ERROR) << "Unable to write to the database: " << status.ToString(); | |
49 return false; | |
50 } | |
51 | |
52 // Increments the next available notification id. |current_notification_id| | |
53 // must be the most recently used notification id. Returns whether the new | |
54 // value was written successfully. | |
55 // | |
56 // TODO(peter): Stop doing this manually when writing notification data will | |
57 // do this for us, except for tests verifying corruption behavior. | |
58 bool IncrementNextNotificationId(NotificationDatabase* database, | |
59 int64_t current_notification_id) { | |
60 leveldb::WriteBatch batch; | |
61 database->IncrementNextNotificationId(&batch, current_notification_id); | |
62 | |
63 leveldb::Status status = database->db()->Write(leveldb::WriteOptions(), | |
64 &batch); | |
65 if (status.ok()) | |
66 return true; | |
67 | |
68 LOG(ERROR) << "Unable to increment the next notification id: " | |
69 << status.ToString(); | |
70 return false; | |
71 } | |
34 }; | 72 }; |
35 | 73 |
36 TEST_F(NotificationDatabaseTest, OpenCloseMemory) { | 74 TEST_F(NotificationDatabaseTest, OpenCloseMemory) { |
37 scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 75 scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
38 | 76 |
39 // Should return false because the database does not exist in memory. | 77 // Should return false because the database does not exist in memory. |
40 EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, | 78 EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, |
41 database->Open(false /* create_if_missing */)); | 79 database->Open(false /* create_if_missing */)); |
42 | 80 |
43 // Should return true, indicating that the database could be created. | 81 // Should return true, indicating that the database could be created. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 ASSERT_EQ(NotificationDatabase::STATUS_OK, database->Destroy()); | 132 ASSERT_EQ(NotificationDatabase::STATUS_OK, database->Destroy()); |
95 EXPECT_FALSE(IsDatabaseOpen(database.get())); | 133 EXPECT_FALSE(IsDatabaseOpen(database.get())); |
96 | 134 |
97 // Try to re-open the database (but not re-create it). This should fail as | 135 // Try to re-open the database (but not re-create it). This should fail as |
98 // the files associated with the database should have been blown away. | 136 // the files associated with the database should have been blown away. |
99 database.reset(CreateDatabaseOnFileSystem(database_dir.path())); | 137 database.reset(CreateDatabaseOnFileSystem(database_dir.path())); |
100 EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, | 138 EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, |
101 database->Open(false /* create_if_missing */)); | 139 database->Open(false /* create_if_missing */)); |
102 } | 140 } |
103 | 141 |
142 TEST_F(NotificationDatabaseTest, GetNextNotificationIdIncrements) { | |
143 base::ScopedTempDir database_dir; | |
144 ASSERT_TRUE(database_dir.CreateUniqueTempDir()); | |
145 | |
146 scoped_ptr<NotificationDatabase> database( | |
147 CreateDatabaseOnFileSystem(database_dir.path())); | |
148 | |
149 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
150 database->Open(true /* create_if_missing */)); | |
151 | |
152 int64_t notification_id = 0; | |
153 | |
154 // Verify that getting two ids on the same database instance results in | |
155 // incrementing values. Notification ids will start at 1. | |
156 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
157 database->GetNextNotificationId(¬ification_id)); | |
158 EXPECT_EQ(1, notification_id); | |
159 | |
160 EXPECT_TRUE(IncrementNextNotificationId(database.get(), notification_id)); | |
161 | |
162 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
163 database->GetNextNotificationId(¬ification_id)); | |
164 EXPECT_EQ(2, notification_id); | |
165 | |
166 EXPECT_TRUE(IncrementNextNotificationId(database.get(), notification_id)); | |
167 | |
168 database.reset(CreateDatabaseOnFileSystem(database_dir.path())); | |
169 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
170 database->Open(false /* create_if_missing */)); | |
171 | |
172 // Verify that the next notification id was stored in the database, and | |
173 // continues where we expect it to be, even after closing and opening it. | |
174 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
175 database->GetNextNotificationId(¬ification_id)); | |
176 EXPECT_EQ(3, notification_id); | |
177 } | |
178 | |
179 TEST_F(NotificationDatabaseTest, GetNextNotificationIdCorruption) { | |
180 scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | |
181 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
182 database->Open(true /* create_if_missing */)); | |
183 | |
184 int64_t notification_id = 0; | |
185 | |
186 ASSERT_EQ(NotificationDatabase::STATUS_OK, | |
187 database->GetNextNotificationId(¬ification_id)); | |
188 EXPECT_EQ(1, notification_id); | |
189 | |
190 // Deliberately write an invalid value as the next notification id to the | |
Bernhard Bauer
2015/03/11 22:02:38
Nit: "ID" in uppercase.
Peter Beverloo
2015/03/11 22:33:33
I've got it in lowercase everywhere in Notificatio
| |
191 // database, which should cause GetNextNotificationId to realize that | |
192 // something is wrong with the data it's reading. | |
193 ASSERT_TRUE(WriteLevelDBKeyValuePair(database.get(), | |
194 "NEXT_NOTIFICATION_ID", | |
195 "-42")); | |
196 | |
197 EXPECT_EQ(NotificationDatabase::STATUS_ERROR_CORRUPTED, | |
198 database->GetNextNotificationId(¬ification_id)); | |
199 } | |
200 | |
104 } // namespace content | 201 } // namespace content |
OLD | NEW |