aboutsummaryrefslogtreecommitdiffstats
path: root/tests/unit
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2018-04-03 14:34:51 +0200
committerMarco Bubke <marco.bubke@qt.io>2018-04-04 13:35:37 +0000
commit23865a102d9225ac3167cf9454d30a16f8c4f4ee (patch)
tree6e29eea1f935e25bce466ed87564ccdc42a71a86 /tests/unit
parentc5f9765c9379df0433c8811d7bf41534ff118925 (diff)
Clang: Handle constraint exceptions in the file path storage
It can be happen that the entry is written by an other connection after we tried to read and before we write. This would lead to a double entry which be prevented by the unique index in the database. In that case we simply try again and read the id from the database. Change-Id: I6c9d94e95ae11556bb446813f64be0855be4ddbe Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/unittest/filepathstorage-test.cpp91
1 files changed, 89 insertions, 2 deletions
diff --git a/tests/unit/unittest/filepathstorage-test.cpp b/tests/unit/unittest/filepathstorage-test.cpp
index 322c50863c..f20ee52225 100644
--- a/tests/unit/unittest/filepathstorage-test.cpp
+++ b/tests/unit/unittest/filepathstorage-test.cpp
@@ -235,7 +235,7 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceIdForUnknownEntry)
storage.fetchSourceId(5, "unknownfile.h");
}
-TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheDatabaseIsBusyInBeginBecauseTheTableAlreadyChanged)
+TEST_F(FilePathStorage, RestartFetchDirectoryIDIfTheDatabaseIsBusyInBeginBecauseTheTableAlreadyChanged)
{
InSequence s;
@@ -269,7 +269,25 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheDat
storage.fetchDirectoryId("/other/unknow/path");
}
-TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheDatabaseIsBusyInBeginBecauseTheTableAlreadyChanged)
+TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheIndexIsConstraintBecauseTheEntryExistsAlready)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase,deferredBegin());
+ EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
+ valueReturnInt32(Eq("/other/unknow/path")));
+ EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path")))
+ .WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy")));
+ EXPECT_CALL(mockDatabase, rollback());
+ EXPECT_CALL(mockDatabase,deferredBegin());
+ EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
+ valueReturnInt32(Eq("/other/unknow/path")));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchDirectoryId("/other/unknow/path");
+}
+
+TEST_F(FilePathStorage, RestartFetchSourceIdIfTheDatabaseIsBusyInBeginBecauseTheTableAlreadyChanged)
{
InSequence s;
@@ -303,6 +321,24 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheDatabase
storage.fetchSourceId(5, "otherunknownfile.h");
}
+TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheIndexIsConstraintBecauseTheEntryExistsAlready)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase,deferredBegin());
+ EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
+ valueReturnInt32(5, Eq("otherunknownfile.h")));
+ EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h")))
+ .WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy")));;
+ EXPECT_CALL(mockDatabase, rollback());
+ EXPECT_CALL(mockDatabase,deferredBegin());
+ EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
+ valueReturnInt32(5, Eq("otherunknownfile.h")));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchSourceId(5, "otherunknownfile.h");
+}
+
TEST_F(FilePathStorage, SelectAllDirectories)
{
auto directories = storage.fetchAllDirectories();
@@ -379,6 +415,57 @@ TEST_F(FilePathStorage, ThrowAsFetchingSourceNameForNonExistingId)
ASSERT_THROW(storage.fetchSourceName(12), ClangBackEnd::SourceNameIdDoesNotExists);
}
+TEST_F(FilePathStorage, RestartFetchSourceNameIfTheDatabaseIsBusyInBegin)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
+ EXPECT_CALL(mockDatabase, rollback()).Times(0);
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectSourceNameFromSourcesBySourceId, valueReturnSmallString(42));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchSourceName(42);
+}
+
+TEST_F(FilePathStorage, RestartFetchDirectoryPathIfTheDatabaseIsBusyInBegin)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
+ EXPECT_CALL(mockDatabase, rollback()).Times(0);
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectDirectoryPathFromDirectoriesByDirectoryId, valueReturnPathString(5)); EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchDirectoryPath(5);
+}
+
+TEST_F(FilePathStorage, RestartFetchAllDirectoriesIfBeginIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
+ EXPECT_CALL(mockDatabase, rollback()).Times(0);
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectAllDirectories, valuesReturnStdVectorDirectory(256));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchAllDirectories();
+}
+
+TEST_F(FilePathStorage, RestartFetchAllSourcesIfBeginIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
+ EXPECT_CALL(mockDatabase, rollback()).Times(0);
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectAllSources, valuesReturnStdVectorSource(8192));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchAllSources();
+}
+
void FilePathStorage::SetUp()
{
ON_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,