OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "sql/connection.h" | 9 #include "sql/connection.h" |
10 #include "sql/meta_table.h" | 10 #include "sql/meta_table.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 void ErrorCallbackResetHelper(sql::Connection* db, | 64 void ErrorCallbackResetHelper(sql::Connection* db, |
65 size_t* counter, | 65 size_t* counter, |
66 const RefCounter& r, | 66 const RefCounter& r, |
67 int error, sql::Statement* stmt) { | 67 int error, sql::Statement* stmt) { |
68 // The ref count should not go to zero when clearing the callback. | 68 // The ref count should not go to zero when clearing the callback. |
69 EXPECT_GT(*counter, 0u); | 69 EXPECT_GT(*counter, 0u); |
70 db->reset_error_callback(); | 70 db->reset_error_callback(); |
71 EXPECT_GT(*counter, 0u); | 71 EXPECT_GT(*counter, 0u); |
72 } | 72 } |
73 | 73 |
74 // Set a umask and restore the old mask on destruction. | |
75 class ScopedUmaskSetter { | |
76 public: | |
77 explicit ScopedUmaskSetter(mode_t target_mask) { | |
78 old_umask_ = umask(target_mask); | |
79 } | |
80 ~ScopedUmaskSetter() { umask(old_umask_); } | |
81 private: | |
82 mode_t old_umask_; | |
83 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter); | |
84 }; | |
85 | |
74 class SQLConnectionTest : public testing::Test { | 86 class SQLConnectionTest : public testing::Test { |
75 public: | 87 public: |
76 SQLConnectionTest() {} | 88 SQLConnectionTest() {} |
77 | 89 |
78 virtual void SetUp() { | 90 virtual void SetUp() { |
79 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 91 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
80 ASSERT_TRUE(db_.Open(db_path())); | 92 ASSERT_TRUE(db_.Open(db_path())); |
81 } | 93 } |
82 | 94 |
83 virtual void TearDown() { | 95 virtual void TearDown() { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 TEST_F(SQLConnectionTest, ErrorCallback) { | 230 TEST_F(SQLConnectionTest, ErrorCallback) { |
219 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)"; | 231 const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)"; |
220 ASSERT_TRUE(db().Execute(kCreateSql)); | 232 ASSERT_TRUE(db().Execute(kCreateSql)); |
221 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)")); | 233 ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)")); |
222 | 234 |
223 int error = SQLITE_OK; | 235 int error = SQLITE_OK; |
224 { | 236 { |
225 sql::ScopedErrorCallback sec( | 237 sql::ScopedErrorCallback sec( |
226 &db(), base::Bind(&sql::CaptureErrorCallback, &error)); | 238 &db(), base::Bind(&sql::CaptureErrorCallback, &error)); |
227 | 239 |
228 // Inserting something other than a number into the primary key | 240 // Inserting something other than a number into the primary key |
Greg Billock
2013/07/16 20:44:05
obsolete comment? Looks like you're aiming at the
Scott Hess - ex-Googler
2013/07/16 21:03:09
Ah, I think this is copied forward from a differen
| |
229 // should result in the callback seeing SQLITE_MISMATCH. | 241 // should result in the callback seeing SQLITE_MISMATCH. |
230 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); | 242 EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); |
231 EXPECT_EQ(SQLITE_CONSTRAINT, error); | 243 EXPECT_EQ(SQLITE_CONSTRAINT, error); |
232 } | 244 } |
233 | 245 |
234 // Callback is no longer in force due to reset. | 246 // Callback is no longer in force due to reset. |
235 { | 247 { |
236 error = SQLITE_OK; | 248 error = SQLITE_OK; |
237 sql::ScopedErrorIgnorer ignore_errors; | 249 sql::ScopedErrorIgnorer ignore_errors; |
238 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); | 250 ignore_errors.IgnoreError(SQLITE_CONSTRAINT); |
239 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); | 251 ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)")); |
240 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); | 252 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); |
241 EXPECT_EQ(SQLITE_OK, error); | 253 EXPECT_EQ(SQLITE_OK, error); |
242 } | 254 } |
243 | 255 |
244 // base::Bind() can curry arguments to be passed by const reference | 256 // base::Bind() can curry arguments to be passed by const reference |
Greg Billock
2013/07/16 20:44:05
I think these are good tests, but I think after a
Scott Hess - ex-Googler
2013/07/16 21:03:09
The comment already mentioned the callback setting
| |
245 // to the callback function. If the callback function causes | 257 // to the callback function. If the callback function causes |
246 // re/set_error_callback() to be called, the storage for those | 258 // re/set_error_callback() to be called, the storage for those |
247 // arguments can be deleted. | 259 // arguments can be deleted. |
248 // | 260 // |
249 // RefCounter() counts how many objects are live using an external | 261 // RefCounter() counts how many objects are live using an external |
250 // count. The same counter is passed to the callback, so that it | 262 // count. The same counter is passed to the callback, so that it |
251 // can check directly even if the RefCounter object is no longer | 263 // can check directly even if the RefCounter object is no longer |
252 // live. | 264 // live. |
253 { | 265 { |
254 size_t count = 0; | 266 size_t count = 0; |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
655 // of journal_mode PERSIST. | 667 // of journal_mode PERSIST. |
656 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal")); | 668 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal")); |
657 ASSERT_TRUE(base::PathExists(db_path())); | 669 ASSERT_TRUE(base::PathExists(db_path())); |
658 ASSERT_TRUE(base::PathExists(journal)); | 670 ASSERT_TRUE(base::PathExists(journal)); |
659 | 671 |
660 sql::Connection::Delete(db_path()); | 672 sql::Connection::Delete(db_path()); |
661 EXPECT_FALSE(base::PathExists(db_path())); | 673 EXPECT_FALSE(base::PathExists(db_path())); |
662 EXPECT_FALSE(base::PathExists(journal)); | 674 EXPECT_FALSE(base::PathExists(journal)); |
663 } | 675 } |
664 | 676 |
677 #if defined(OS_POSIX) | |
678 // Test that set_restrict_to_user() trims database permissions so that | |
679 // only the owner (and root) can read. | |
680 TEST_F(SQLConnectionTest, UserPermission) { | |
681 // If the bots all had a restrictive umask setting such that | |
682 // databases are always created with only the owner able to read | |
683 // them, then the code could break without breaking the tests. | |
684 // Temporarily provide a more permissive umask. | |
685 db().Close(); | |
686 sql::Connection::Delete(db_path()); | |
687 ASSERT_FALSE(base::PathExists(db_path())); | |
688 ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH); | |
689 ASSERT_TRUE(db().Open(db_path())); | |
690 | |
691 // Cause the journal file to be created. If the default | |
692 // journal_mode is changed back to DELETE, then parts of this test | |
693 // will need to be updated. | |
694 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)")); | |
695 | |
696 base::FilePath journal(db_path().value() + FILE_PATH_LITERAL("-journal")); | |
697 int mode; | |
698 | |
699 // Given a permissive umask, the database is created with permissive | |
700 // read access for the database and journal. | |
701 ASSERT_TRUE(base::PathExists(db_path())); | |
702 ASSERT_TRUE(base::PathExists(journal)); | |
703 mode = file_util::FILE_PERMISSION_MASK; | |
704 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode)); | |
705 ASSERT_NE((mode & file_util::FILE_PERMISSION_USER_MASK), mode); | |
706 mode = file_util::FILE_PERMISSION_MASK; | |
707 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode)); | |
708 ASSERT_NE((mode & file_util::FILE_PERMISSION_USER_MASK), mode); | |
709 | |
710 // Re-open with restricted permissions and verify that the modes | |
711 // changed for both the main database and the journal. | |
712 db().Close(); | |
713 db().set_restrict_to_user(); | |
714 ASSERT_TRUE(db().Open(db_path())); | |
715 ASSERT_TRUE(base::PathExists(db_path())); | |
716 ASSERT_TRUE(base::PathExists(journal)); | |
717 mode = file_util::FILE_PERMISSION_MASK; | |
718 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode)); | |
719 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); | |
720 mode = file_util::FILE_PERMISSION_MASK; | |
721 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode)); | |
722 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); | |
723 | |
724 // Delete and re-create the database, the restriction should still apply. | |
725 db().Close(); | |
726 sql::Connection::Delete(db_path()); | |
727 ASSERT_TRUE(db().Open(db_path())); | |
728 ASSERT_TRUE(base::PathExists(db_path())); | |
729 ASSERT_FALSE(base::PathExists(journal)); | |
730 mode = file_util::FILE_PERMISSION_MASK; | |
731 EXPECT_TRUE(file_util::GetPosixFilePermissions(db_path(), &mode)); | |
732 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); | |
733 | |
734 // Verify that journal creation inherits the restriction. | |
735 EXPECT_TRUE(db().Execute("CREATE TABLE x (x)")); | |
736 ASSERT_TRUE(base::PathExists(journal)); | |
737 mode = file_util::FILE_PERMISSION_MASK; | |
738 EXPECT_TRUE(file_util::GetPosixFilePermissions(journal, &mode)); | |
739 ASSERT_EQ((mode & file_util::FILE_PERMISSION_USER_MASK), mode); | |
740 } | |
741 #endif // defined(OS_POSIX) | |
742 | |
665 } // namespace | 743 } // namespace |
OLD | NEW |