2018-10-11 18:09:55 +02:00
/****************************************************************************
* *
* * Copyright ( C ) 2017 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
* *
* * This file is part of Qt Creator .
* *
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
* * a written agreement between you and The Qt Company . For licensing terms
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
* *
* * GNU General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3 as published by the Free Software
* * Foundation with exceptions as appearing in the file LICENSE . GPL3 - EXCEPT
* * included in the packaging of this file . Please review the following
* * information to ensure the GNU General Public License requirements will
* * be met : https : //www.gnu.org/licenses/gpl-3.0.html.
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "googletest.h"
# include "mockfilepathcaching.h"
# include "mocksqlitedatabase.h"
# include <sqlitedatabase.h>
2018-11-07 17:48:25 +01:00
# include <builddependenciesstorage.h>
2018-10-11 18:09:55 +02:00
# include <utils/optional.h>
namespace {
using ClangBackEnd : : FilePathCachingInterface ;
2019-03-13 15:09:30 +01:00
using ClangBackEnd : : FilePathId ;
using ClangBackEnd : : ProjectPartId ;
2018-11-07 17:48:25 +01:00
using ClangBackEnd : : SourceEntries ;
using ClangBackEnd : : SourceType ;
using ClangBackEnd : : UsedMacro ;
2018-10-11 18:09:55 +02:00
using Sqlite : : Database ;
using Sqlite : : Table ;
2019-03-13 15:09:30 +01:00
using Utils : : PathString ;
2018-10-11 18:09:55 +02:00
2018-11-07 17:48:25 +01:00
using Storage = ClangBackEnd : : BuildDependenciesStorage < MockSqliteDatabase > ;
2018-10-11 18:09:55 +02:00
2018-11-07 17:48:25 +01:00
class BuildDependenciesStorage : public testing : : Test
2018-10-11 18:09:55 +02:00
{
protected :
NiceMock < MockSqliteDatabase > mockDatabase ;
Storage storage { mockDatabase } ;
2018-11-20 16:20:41 +01:00
MockSqliteWriteStatement & insertIntoNewUsedMacrosStatement = storage . insertIntoNewUsedMacrosStatement ;
MockSqliteWriteStatement & syncNewUsedMacrosStatement = storage . syncNewUsedMacrosStatement ;
MockSqliteWriteStatement & deleteOutdatedUsedMacrosStatement = storage . deleteOutdatedUsedMacrosStatement ;
MockSqliteWriteStatement & deleteNewUsedMacrosTableStatement = storage . deleteNewUsedMacrosTableStatement ;
2019-02-25 19:07:19 +01:00
MockSqliteWriteStatement & insertOrUpdateFileStatusesStatement = storage . insertOrUpdateFileStatusesStatement ;
2018-11-20 16:20:41 +01:00
MockSqliteWriteStatement & insertIntoNewSourceDependenciesStatement = storage . insertIntoNewSourceDependenciesStatement ;
MockSqliteWriteStatement & syncNewSourceDependenciesStatement = storage . syncNewSourceDependenciesStatement ;
MockSqliteWriteStatement & deleteOutdatedSourceDependenciesStatement = storage . deleteOutdatedSourceDependenciesStatement ;
MockSqliteWriteStatement & deleteNewSourceDependenciesStatement = storage . deleteNewSourceDependenciesStatement ;
MockSqliteReadStatement & getLowestLastModifiedTimeOfDependencies = storage . getLowestLastModifiedTimeOfDependencies ;
2019-03-13 15:09:30 +01:00
MockSqliteWriteStatement & insertOrUpdateProjectPartsFilesStatement = storage . insertOrUpdateProjectPartsFilesStatement ;
2018-11-20 16:20:41 +01:00
MockSqliteReadStatement & fetchSourceDependenciesStatement = storage . fetchSourceDependenciesStatement ;
MockSqliteReadStatement & fetchProjectPartIdStatement = storage . fetchProjectPartIdStatement ;
MockSqliteReadStatement & fetchUsedMacrosStatement = storage . fetchUsedMacrosStatement ;
2019-02-25 19:07:19 +01:00
MockSqliteWriteStatement & insertProjectPartNameStatement = storage . insertProjectPartNameStatement ;
MockSqliteWriteStatement & updatePchCreationTimeStampStatement = storage . updatePchCreationTimeStampStatement ;
2019-03-13 15:09:30 +01:00
MockSqliteWriteStatement & deleteAllProjectPartsFilesWithProjectPartNameStatement
= storage . deleteAllProjectPartsFilesWithProjectPartNameStatement ;
2018-10-11 18:09:55 +02:00
} ;
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , ConvertStringsToJson )
2018-10-11 18:09:55 +02:00
{
Utils : : SmallStringVector strings { " foo " , " bar " , " foo " } ;
auto jsonText = storage . toJson ( strings ) ;
ASSERT_THAT ( jsonText , Eq ( " [ \" foo \" , \" bar \" , \" foo \" ] " ) ) ;
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , InsertOrUpdateUsedMacros )
2018-10-11 18:09:55 +02:00
{
InSequence sequence ;
2019-02-25 19:07:19 +01:00
EXPECT_CALL ( insertIntoNewUsedMacrosStatement ,
write ( TypedEq < int > ( 42 ) , TypedEq < Utils : : SmallStringView > ( " FOO " ) ) ) ;
EXPECT_CALL ( insertIntoNewUsedMacrosStatement ,
write ( TypedEq < int > ( 43 ) , TypedEq < Utils : : SmallStringView > ( " BAR " ) ) ) ;
2018-10-11 18:09:55 +02:00
EXPECT_CALL ( syncNewUsedMacrosStatement , execute ( ) ) ;
EXPECT_CALL ( deleteOutdatedUsedMacrosStatement , execute ( ) ) ;
EXPECT_CALL ( deleteNewUsedMacrosTableStatement , execute ( ) ) ;
2018-11-06 19:02:00 +01:00
storage . insertOrUpdateUsedMacros ( { { " FOO " , 42 } , { " BAR " , 43 } } ) ;
2018-10-11 18:09:55 +02:00
}
2019-02-25 19:07:19 +01:00
TEST_F ( BuildDependenciesStorage , InsertOrUpdateFileStatuses )
2018-10-11 18:09:55 +02:00
{
2019-02-25 19:07:19 +01:00
EXPECT_CALL ( insertOrUpdateFileStatusesStatement ,
write ( TypedEq < int > ( 42 ) , TypedEq < off_t > ( 1 ) , TypedEq < time_t > ( 2 ) ) ) ;
EXPECT_CALL ( insertOrUpdateFileStatusesStatement ,
write ( TypedEq < int > ( 43 ) , TypedEq < off_t > ( 4 ) , TypedEq < time_t > ( 5 ) ) ) ;
2018-10-11 18:09:55 +02:00
2019-02-25 19:07:19 +01:00
storage . insertOrUpdateFileStatuses ( { { 42 , 1 , 2 } , { 43 , 4 , 5 } } ) ;
2018-10-11 18:09:55 +02:00
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , InsertOrUpdateSourceDependencies )
2018-10-11 18:09:55 +02:00
{
InSequence sequence ;
EXPECT_CALL ( insertIntoNewSourceDependenciesStatement , write ( TypedEq < int > ( 42 ) , TypedEq < int > ( 1 ) ) ) ;
EXPECT_CALL ( insertIntoNewSourceDependenciesStatement , write ( TypedEq < int > ( 42 ) , TypedEq < int > ( 2 ) ) ) ;
EXPECT_CALL ( syncNewSourceDependenciesStatement , execute ( ) ) ;
EXPECT_CALL ( deleteOutdatedSourceDependenciesStatement , execute ( ) ) ;
EXPECT_CALL ( deleteNewSourceDependenciesStatement , execute ( ) ) ;
2018-11-06 19:02:00 +01:00
storage . insertOrUpdateSourceDependencies ( { { 42 , 1 } , { 42 , 2 } } ) ;
2018-10-11 18:09:55 +02:00
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , AddTablesInConstructor )
2018-10-11 18:09:55 +02:00
{
InSequence s ;
EXPECT_CALL ( mockDatabase , immediateBegin ( ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newUsedMacros(sourceId INTEGER, macroName TEXT) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newUsedMacros_sourceId_macroName ON newUsedMacros(sourceId, macroName) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newSourceDependencies(sourceId INTEGER, dependencySourceId TEXT) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newSourceDependencies_sourceId_dependencySourceId ON newSourceDependencies(sourceId, dependencySourceId) " ) ) ) ;
EXPECT_CALL ( mockDatabase , commit ( ) ) ;
Storage storage { mockDatabase } ;
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , FetchLowestLastModifiedTimeIfNoModificationTimeExists )
2018-10-11 18:09:55 +02:00
{
EXPECT_CALL ( getLowestLastModifiedTimeOfDependencies , valueReturnInt64 ( Eq ( 1 ) ) ) ;
2018-11-06 19:02:00 +01:00
auto lowestLastModified = storage . fetchLowestLastModifiedTime ( 1 ) ;
2018-10-11 18:09:55 +02:00
ASSERT_THAT ( lowestLastModified , Eq ( 0 ) ) ;
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , FetchLowestLastModifiedTime )
2018-10-11 18:09:55 +02:00
{
EXPECT_CALL ( getLowestLastModifiedTimeOfDependencies , valueReturnInt64 ( Eq ( 21 ) ) )
. WillRepeatedly ( Return ( 12 ) ) ;
2018-11-06 19:02:00 +01:00
auto lowestLastModified = storage . fetchLowestLastModifiedTime ( 21 ) ;
2018-10-11 18:09:55 +02:00
ASSERT_THAT ( lowestLastModified , Eq ( 12 ) ) ;
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , AddNewUsedMacroTable )
2018-10-11 18:09:55 +02:00
{
InSequence s ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newUsedMacros(sourceId INTEGER, macroName TEXT) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newUsedMacros_sourceId_macroName ON newUsedMacros(sourceId, macroName) " ) ) ) ;
2018-10-18 14:36:16 +02:00
storage . createNewUsedMacrosTable ( ) ;
2018-10-11 18:09:55 +02:00
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , AddNewSourceDependenciesTable )
2018-10-11 18:09:55 +02:00
{
InSequence s ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newSourceDependencies(sourceId INTEGER, dependencySourceId TEXT) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newSourceDependencies_sourceId_dependencySourceId ON newSourceDependencies(sourceId, dependencySourceId) " ) ) ) ;
2018-10-18 14:36:16 +02:00
storage . createNewSourceDependenciesTable ( ) ;
2018-10-11 18:09:55 +02:00
}
2018-11-07 17:48:25 +01:00
TEST_F ( BuildDependenciesStorage , UpdateSources )
{
InSequence s ;
2019-02-28 17:52:34 +01:00
SourceEntries entries { { 1 , SourceType : : TopProjectInclude , 10 , ClangBackEnd : : HasMissingIncludes : : Yes } ,
2019-02-25 19:07:19 +01:00
{ 2 , SourceType : : TopSystemInclude , 20 } } ;
2019-03-13 15:09:30 +01:00
EXPECT_CALL ( deleteAllProjectPartsFilesWithProjectPartNameStatement , write ( TypedEq < int > ( 22 ) ) ) ;
EXPECT_CALL ( insertOrUpdateProjectPartsFilesStatement ,
2019-02-28 17:52:34 +01:00
write ( TypedEq < int > ( 1 ) , TypedEq < int > ( 22 ) , TypedEq < uchar > ( 0 ) , TypedEq < uchar > ( 1 ) ) ) ;
2019-03-13 15:09:30 +01:00
EXPECT_CALL ( insertOrUpdateProjectPartsFilesStatement ,
2019-02-28 17:52:34 +01:00
write ( TypedEq < int > ( 2 ) , TypedEq < int > ( 22 ) , TypedEq < uchar > ( 1 ) , TypedEq < uchar > ( 0 ) ) ) ;
2019-02-25 19:07:19 +01:00
storage . insertOrUpdateSources ( entries , 22 ) ;
}
TEST_F ( BuildDependenciesStorage , UpdatePchCreationTimeStamp )
{
InSequence s ;
2018-11-07 17:48:25 +01:00
2019-02-25 19:07:19 +01:00
EXPECT_CALL ( mockDatabase , immediateBegin ( ) ) ;
2019-03-13 15:09:30 +01:00
EXPECT_CALL ( updatePchCreationTimeStampStatement , write ( TypedEq < long long > ( 101 ) , TypedEq < int > ( 1 ) ) ) ;
2019-02-25 19:07:19 +01:00
EXPECT_CALL ( mockDatabase , commit ( ) ) ;
2018-11-07 17:48:25 +01:00
2019-03-13 15:09:30 +01:00
storage . updatePchCreationTimeStamp ( 101 , 1 ) ;
2019-02-25 19:07:19 +01:00
}
TEST_F ( BuildDependenciesStorage , CallsFetchDependSources )
{
EXPECT_CALL ( fetchSourceDependenciesStatement , valuesReturnSourceEntries ( _ , 22 , 20 ) ) ;
2018-11-07 17:48:25 +01:00
2019-02-25 19:07:19 +01:00
storage . fetchDependSources ( 22 , 20 ) ;
2018-11-07 17:48:25 +01:00
}
2019-02-25 19:07:19 +01:00
TEST_F ( BuildDependenciesStorage , FetchDependSources )
2018-11-07 17:48:25 +01:00
{
2018-11-21 20:11:07 +01:00
SourceEntries sourceEntries { { 1 , SourceType : : TopProjectInclude , 10 } , { 2 , SourceType : : TopSystemInclude , 20 } } ;
2018-11-07 17:48:25 +01:00
EXPECT_CALL ( fetchSourceDependenciesStatement , valuesReturnSourceEntries ( _ , 22 , 20 ) ) . WillOnce ( Return ( sourceEntries ) ) ;
2019-02-25 19:07:19 +01:00
auto entries = storage . fetchDependSources ( 22 , 20 ) ;
2018-11-07 17:48:25 +01:00
ASSERT_THAT ( entries , sourceEntries ) ;
}
TEST_F ( BuildDependenciesStorage , CallsFetchUsedMacros )
{
EXPECT_CALL ( fetchUsedMacrosStatement , valuesReturnUsedMacros ( _ , 22 ) ) ;
storage . fetchUsedMacros ( 22 ) ;
}
TEST_F ( BuildDependenciesStorage , FetchUsedMacros )
{
ClangBackEnd : : UsedMacros result { UsedMacro { " YI " , 1 } , UsedMacro { " ER " , 2 } } ;
EXPECT_CALL ( fetchUsedMacrosStatement , valuesReturnUsedMacros ( _ , 22 ) ) . WillOnce ( Return ( result ) ) ;
auto usedMacros = storage . fetchUsedMacros ( 22 ) ;
ASSERT_THAT ( usedMacros , result ) ;
}
2018-10-11 18:09:55 +02:00
}