diff options
author | Marco Bubke <marco.bubke@qt.io> | 2018-04-03 14:34:51 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2018-04-04 13:35:37 +0000 |
commit | 23865a102d9225ac3167cf9454d30a16f8c4f4ee (patch) | |
tree | 6e29eea1f935e25bce466ed87564ccdc42a71a86 /tests/unit | |
parent | c5f9765c9379df0433c8811d7bf41534ff118925 (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.cpp | 91 |
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, |