aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db/src/test
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-17 10:38:17 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-17 12:38:17 +0200
commitbdcfb7eeb7caaeb9019ff0d3946153c33bc6c5e9 (patch)
tree8e0bc944f83d81a003061543f9db9139966ba985 /sonar-db/src/test
parent48697451f2b0ba517c7d1861af3897b4ace896f9 (diff)
downloadsonarqube-bdcfb7eeb7caaeb9019ff0d3946153c33bc6c5e9.tar.gz
sonarqube-bdcfb7eeb7caaeb9019ff0d3946153c33bc6c5e9.zip
Move Java db migrations from sonar-server to sonar-db
Diffstat (limited to 'sonar-db/src/test')
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java136
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java481
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java64
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java35
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java76
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java60
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java319
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java51
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java35
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java57
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java324
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java56
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java66
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java54
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java138
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java102
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java52
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java53
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java88
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java97
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java53
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java53
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java64
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java81
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java88
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java84
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java51
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java59
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java56
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java65
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java49
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java64
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java55
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java55
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java54
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java63
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java66
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java56
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java78
-rw-r--r--sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java56
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml8
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml7
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml5
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml5
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql8
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml5
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml5
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml20
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml17
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml34
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql77
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml35
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml33
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml35
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml31
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml29
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql40
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml12
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml12
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql10
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml15
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml15
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml15
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml134
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql119
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml75
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql18
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml93
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml58
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml40
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml93
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml12
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml57
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml38
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml48
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml113
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql54
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml33
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml33
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql10
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml43
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml50
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml63
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml70
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql32
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql26
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml73
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml3
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml16
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml38
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml94
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml35
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml19
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml38
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml16
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml49
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml24
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql22
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml52
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql16
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql7
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml8
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml25
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql12
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml31
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql14
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml22
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml30
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql52
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml135
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml185
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql59
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml34
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql9
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql7
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml61
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql18
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml26
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql15
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml24
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml29
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml22
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql49
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml68
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml69
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql10
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml100
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml100
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml100
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql22
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql11
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml6
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml13
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml13
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql35
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml10
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml10
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql8
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml6
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml9
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql10
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml9
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml7
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql7
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml26
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml28
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql31
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml29
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml41
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql48
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml17
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml19
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql22
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml20
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml31
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml20
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml31
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml26
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml35
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql17
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml24
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml24
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql32
176 files changed, 8154 insertions, 0 deletions
diff --git a/sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java b/sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java
new file mode 100644
index 00000000000..e5160243c7f
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java
@@ -0,0 +1,136 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version;
+
+import org.junit.Test;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.db.version.AddColumnsBuilder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+
+public class AddColumnsBuilderTest {
+
+ @Test
+ public void add_columns_on_h2() {
+ assertThat(new AddColumnsBuilder(new H2(), "issues")
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("date_in_ms")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true))
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("name")
+ .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+ .setNullable(false)
+ .setLimit(10))
+ .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)");
+ }
+
+ @Test
+ public void add_columns_on_mysql() {
+ assertThat(new AddColumnsBuilder(new MySql(), "issues")
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("date_in_ms")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true))
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("name")
+ .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+ .setNullable(false)
+ .setLimit(10))
+ .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)");
+ }
+
+ @Test
+ public void add_columns_on_oracle() {
+ assertThat(new AddColumnsBuilder(new Oracle(), "issues")
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("date_in_ms")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true))
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("name")
+ .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+ .setNullable(false)
+ .setLimit(10))
+ .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms NUMBER (38) NULL, name VARCHAR (10) NOT NULL)");
+ }
+
+ @Test
+ public void add_columns_on_postgresql() {
+ assertThat(new AddColumnsBuilder(new PostgreSql(), "issues")
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("date_in_ms")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true))
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("name")
+ .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+ .setNullable(false)
+ .setLimit(10))
+ .build()).isEqualTo("ALTER TABLE issues ADD COLUMN date_in_ms BIGINT NULL, ADD COLUMN name VARCHAR (10) NOT NULL");
+ }
+
+ @Test
+ public void add_columns_on_mssql() {
+ assertThat(new AddColumnsBuilder(new MsSql(), "issues")
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("date_in_ms")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true))
+ .addColumn(new AddColumnsBuilder.ColumnDef()
+ .setName("name")
+ .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+ .setNullable(false)
+ .setLimit(10))
+ .build()).isEqualTo("ALTER TABLE issues ADD date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL");
+ }
+
+ @Test
+ public void fail_when_column_name_is_in_upper_case() {
+ try {
+ new AddColumnsBuilder.ColumnDef()
+ .setName("DATE_IN_MS")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true);
+ failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Column name should only contains lowercase and _ characters");
+ }
+ }
+
+ @Test
+ public void fail_when_column_name_contains_invalid_character() {
+ try {
+ new AddColumnsBuilder.ColumnDef()
+ .setName("date-in/ms")
+ .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+ .setNullable(true);
+ failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Column name should only contains lowercase and _ characters");
+ }
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java b/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java
new file mode 100644
index 00000000000..56a5ed91799
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/BaseDataChangeTest.java
@@ -0,0 +1,481 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.BatchSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.Select.Row;
+import org.sonar.db.version.Select.RowReader;
+import org.sonar.test.DbTests;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+@Category(DbTests.class)
+public class BaseDataChangeTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, BaseDataChangeTest.class, "schema.sql");
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table persons");
+ }
+
+ @Test
+ public void query() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ final AtomicBoolean executed = new AtomicBoolean(false);
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ assertThat(context.prepareSelect("select id from persons order by id desc").list(Select.LONG_READER))
+ .containsExactly(3L, 2L, 1L);
+ assertThat(context.prepareSelect("select id from persons where id=?").setLong(1, 2L).get(Select.LONG_READER))
+ .isEqualTo(2L);
+ assertThat(context.prepareSelect("select id from persons where id=?").setLong(1, 12345L).get(Select.LONG_READER))
+ .isNull();
+ executed.set(true);
+ }
+ }.execute();
+ assertThat(executed.get()).isTrue();
+ }
+
+ @Test
+ public void read_column_types() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ final List<Object[]> persons = new ArrayList<>();
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ persons.addAll(context
+ .prepareSelect("select id,login,age,enabled,updated_at,coeff from persons where id=2")
+ .list(new UserReader()));
+ }
+ }.execute();
+ assertThat(persons).hasSize(1);
+ assertThat(persons.get(0)[0]).isEqualTo(2L);
+ assertThat(persons.get(0)[1]).isEqualTo("emmerik");
+ assertThat(persons.get(0)[2]).isEqualTo(14);
+ assertThat(persons.get(0)[3]).isEqualTo(true);
+ assertThat(persons.get(0)[4]).isNotNull();
+ assertThat(persons.get(0)[5]).isEqualTo(5.2);
+ }
+
+ @Test
+ public void parameterized_query() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ final List<Long> ids = new ArrayList<>();
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(Select.LONG_READER));
+ }
+ }.execute();
+ assertThat(ids).containsOnly(2L, 3L);
+ }
+
+ @Test
+ public void display_current_row_details_if_error_during_get() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=2]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).get(new RowReader<Long>() {
+ @Override
+ public Long read(Row row) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ }
+ }.execute();
+
+ }
+
+ @Test
+ public void display_current_row_details_if_error_during_list() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=2]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(new RowReader<Long>() {
+ @Override
+ public Long read(Row row) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ }
+ }.execute();
+
+ }
+
+ @Test
+ public void bad_parameterized_query() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ final List<Long> ids = new ArrayList<>();
+ BaseDataChange change = new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ // parameter value is not set
+ ids.addAll(context.prepareSelect("select id from persons where id>=?").list(Select.LONG_READER));
+ }
+ };
+
+ thrown.expect(SQLException.class);
+
+ change.execute();
+ }
+
+ @Test
+ public void scroll() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ final List<Long> ids = new ArrayList<>();
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.prepareSelect("select id from persons order by id desc").scroll(new Select.RowHandler() {
+ @Override
+ public void handle(Select.Row row) throws SQLException {
+ ids.add(row.getNullableLong(1));
+ }
+ });
+ }
+ }.execute();
+ assertThat(ids).containsExactly(3L, 2L, 1L);
+ }
+
+ @Test
+ public void insert() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)")
+ .setLong(1, 10L)
+ .setString(2, "kurt")
+ .setInt(3, 27)
+ .setBoolean(4, true)
+ .setDouble(5, 2.2)
+ .execute().commit().close();
+ }
+ }.execute();
+
+ db.assertDbUnit(getClass(), "insert-result.xml", "persons");
+ }
+
+ @Test
+ public void batch_insert() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ Upsert upsert = context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)");
+ upsert
+ .setLong(1, 10L)
+ .setString(2, "kurt")
+ .setInt(3, 27)
+ .setBoolean(4, true)
+ .setDouble(5, 2.2)
+ .addBatch();
+ upsert
+ .setLong(1, 11L)
+ .setString(2, "courtney")
+ .setInt(3, 25)
+ .setBoolean(4, false)
+ .setDouble(5, 2.3)
+ .addBatch();
+ upsert.execute().commit().close();
+ }
+ }.execute();
+
+ db.assertDbUnit(getClass(), "batch-insert-result.xml", "persons");
+ }
+
+ @Test
+ public void update_null() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ Upsert upsert = context.prepareUpsert("update persons set login=?,age=?,enabled=?, updated_at=?, coeff=? where id=?");
+ upsert
+ .setString(1, null)
+ .setInt(2, null)
+ .setBoolean(3, null)
+ .setDate(4, null)
+ .setDouble(5, null)
+ .setLong(6, 2L)
+ .execute()
+ .commit()
+ .close();
+ }
+ }.execute();
+
+ db.assertDbUnit(getClass(), "update-null-result.xml", "persons");
+ }
+
+ @Test
+ public void mass_batch_insert() throws Exception {
+ db.executeUpdateSql("truncate table persons");
+
+ final int count = BatchSession.MAX_BATCH_SIZE + 10;
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ Upsert upsert = context.prepareUpsert("insert into persons(id,login,age,enabled,coeff) values (?,?,?,?,?)");
+ for (int i = 0; i < count; i++) {
+ upsert
+ .setLong(1, 10L + i)
+ .setString(2, "login" + i)
+ .setInt(3, 10 + i)
+ .setBoolean(4, true)
+ .setDouble(4, i + 0.5)
+ .addBatch();
+ }
+ upsert.execute().commit().close();
+
+ }
+ }.execute();
+
+ assertThat(db.countRowsOfTable("persons")).isEqualTo(count);
+ }
+
+ @Test
+ public void scroll_and_update() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?");
+ context.prepareSelect("select id from persons").scroll(new Select.RowHandler() {
+ @Override
+ public void handle(Select.Row row) throws SQLException {
+ long id = row.getNullableLong(1);
+ upsert.setString(1, "login" + id).setInt(2, 10 + (int) id).setLong(3, id);
+ upsert.execute();
+ }
+ });
+ upsert.commit().close();
+ }
+ }.execute();
+
+ db.assertDbUnit(getClass(), "scroll-and-update-result.xml", "persons");
+ }
+
+ @Test
+ public void display_current_row_details_if_error_during_scroll() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=1]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?");
+ context.prepareSelect("select id from persons").scroll(new Select.RowHandler() {
+ @Override
+ public void handle(Select.Row row) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ upsert.commit().close();
+ }
+ }.execute();
+ }
+
+ @Test
+ public void mass_update() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
+ massUpdate.update("update persons set login=?, age=? where id=?");
+ massUpdate.execute(new MassUpdate.Handler() {
+ @Override
+ public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+ long id = row.getNullableLong(1);
+ update
+ .setString(1, "login" + id)
+ .setInt(2, 10 + (int) id)
+ .setLong(3, id);
+ return true;
+ }
+ });
+ }
+ }.execute();
+
+ db.assertDbUnit(getClass(), "mass-update-result.xml", "persons");
+ }
+
+ @Test
+ public void display_current_row_details_if_error_during_mass_update() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=2]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
+ massUpdate.update("update persons set login=?, age=? where id=?");
+ massUpdate.execute(new MassUpdate.Handler() {
+ @Override
+ public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ }
+ }.execute();
+ }
+
+ @Test
+ public void mass_update_nothing() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
+ massUpdate.update("update persons set login=?, age=? where id=?");
+ massUpdate.execute(new MassUpdate.Handler() {
+ @Override
+ public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+ return false;
+ }
+ });
+ }
+ }.execute();
+
+ db.assertDbUnit(getClass(), "persons.xml", "persons");
+ }
+
+ @Test
+ public void bad_mass_update() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ BaseDataChange change = new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
+ // update is not set
+ massUpdate.execute(new MassUpdate.Handler() {
+ @Override
+ public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+ return false;
+ }
+ });
+ }
+ };
+ try {
+ change.execute();
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("SELECT or UPDATE requests are not defined");
+ }
+ }
+
+ @Test
+ public void read_not_null_fields() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ final List<Object[]> persons = new ArrayList<>();
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ persons.addAll(context
+ .prepareSelect("select id,login,age,enabled,updated_at,coeff from persons where id=2")
+ .list(new Select.RowReader<Object[]>() {
+ @Override
+ public Object[] read(Select.Row row) throws SQLException {
+ return new Object[] {
+ // id, login, age, enabled
+ row.getLong(1),
+ row.getString(2),
+ row.getInt(3),
+ row.getBoolean(4),
+ row.getDate(5),
+ row.getDouble(6),
+ };
+ }
+ }));
+ }
+ }.execute();
+ assertThat(persons).hasSize(1);
+ assertThat(persons.get(0)[0]).isEqualTo(2L);
+ assertThat(persons.get(0)[1]).isEqualTo("emmerik");
+ assertThat(persons.get(0)[2]).isEqualTo(14);
+ assertThat(persons.get(0)[3]).isEqualTo(true);
+ assertThat(persons.get(0)[4]).isNotNull();
+ assertThat(persons.get(0)[5]).isEqualTo(5.2);
+ }
+
+ static class UserReader implements Select.RowReader<Object[]> {
+ @Override
+ public Object[] read(Select.Row row) throws SQLException {
+ return new Object[] {
+ // id, login, age, enabled
+ row.getNullableLong(1),
+ row.getNullableString(2),
+ row.getNullableInt(3),
+ row.getNullableBoolean(4),
+ row.getNullableDate(5),
+ row.getNullableDouble(6),
+ };
+ }
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java b/sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java
new file mode 100644
index 00000000000..e7c6955f185
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/DropColumnsBuilderTest.java
@@ -0,0 +1,64 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version;
+
+import org.junit.Test;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.db.version.DropColumnsBuilder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DropColumnsBuilderTest {
+
+ @Test
+ public void drop_columns_on_mysql() {
+ assertThat(new DropColumnsBuilder(new MySql(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, DROP COLUMN name");
+ }
+
+ @Test
+ public void drop_columns_on_oracle() {
+ assertThat(new DropColumnsBuilder(new Oracle(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP (date_in_ms, name)");
+ }
+
+ @Test
+ public void drop_columns_on_postgresql() {
+ assertThat(new DropColumnsBuilder(new PostgreSql(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, DROP COLUMN name");
+ }
+
+ @Test
+ public void drop_columns_on_mssql() {
+ assertThat(new DropColumnsBuilder(new MsSql(), "issues", "date_in_ms", "name")
+ .build()).isEqualTo("ALTER TABLE issues DROP COLUMN date_in_ms, name");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void fail_to_drop_columns_on_h2() {
+ new DropColumnsBuilder(new H2(), "issues", "date_in_ms", "name")
+ .build();
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java
new file mode 100644
index 00000000000..6c3fb4cba25
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+import org.sonar.db.version.MigrationStepModule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MigrationStepModuleTest {
+ @Test
+ public void verify_count_of_added_MigrationStep_types() {
+ ComponentContainer container = new ComponentContainer();
+ new MigrationStepModule().configure(container);
+ assertThat(container.size()).isEqualTo(38);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java
new file mode 100644
index 00000000000..eb291dda5c9
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest.java
@@ -0,0 +1,76 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v451;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AddMissingCustomRuleParametersMigrationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddMissingCustomRuleParametersMigrationTest.class, "schema.sql");
+
+ MigrationStep migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table rules");
+ db.executeUpdateSql("truncate table rules_parameters");
+ migration = new AddMissingCustomRuleParametersMigrationStep(db.getDbClient(), system);
+ when(system.now()).thenReturn(DateUtils.parseDate("2014-10-09").getTime());
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "execute.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "execute-result.xml", "rules", "rules_parameters");
+ }
+
+ @Test
+ public void execute_when_custom_rule_have_no_parameter() throws Exception {
+ db.prepareDbUnit(getClass(), "execute_when_custom_rule_have_no_parameter.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "execute_when_custom_rule_have_no_parameter-result.xml", "rules", "rules_parameters");
+ }
+
+ @Test
+ public void no_changes() throws Exception {
+ db.prepareDbUnit(getClass(), "no_changes.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "no_changes.xml", "rules", "rules_parameters");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java
new file mode 100644
index 00000000000..00808bb8f0a
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest.java
@@ -0,0 +1,60 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v451;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DeleteUnescapedActivitiesTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, DeleteUnescapedActivitiesTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Test
+ public void execute() throws Exception {
+ migration = new DeleteUnescapedActivities(db.database());
+ db.prepareDbUnit(getClass(), "execute.xml");
+ migration.execute();
+ db.assertDbUnit(getClass(), "execute-result.xml", "activities");
+ }
+
+ @Test
+ public void is_unescaped() {
+ assertThat(DeleteUnescapedActivities.isUnescaped(
+ "ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;profileKey=java-findbugs-74105;severity=MAJOR;" +
+ "key=java-findbugs-74105:findbugs:PT_RELATIVE_PATH_TRAVERSAL"))
+ .isFalse();
+ assertThat(DeleteUnescapedActivities.isUnescaped(null)).isFalse();
+ assertThat(DeleteUnescapedActivities.isUnescaped("")).isFalse();
+ assertThat(DeleteUnescapedActivities.isUnescaped("foo=bar")).isFalse();
+ assertThat(DeleteUnescapedActivities.isUnescaped("param_xpath=/foo/bar")).isFalse();
+
+ assertThat(DeleteUnescapedActivities.isUnescaped("param_xpath=/foo/bar;foo;ruleKey=S001")).isTrue();
+ assertThat(DeleteUnescapedActivities.isUnescaped("param_xpath=/foo=foo;ruleKey=S001")).isTrue();
+
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java
new file mode 100644
index 00000000000..1ac8362180a
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java
@@ -0,0 +1,319 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v50;
+
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.dbutils.DbUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedFileSourcesTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedFileSourcesTest.class, "schema.sql");
+
+ private static final long NOW = 1414770242000L;
+
+ FeedFileSources migration;
+
+ System2 system;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table metrics");
+ db.executeUpdateSql("truncate table snapshots");
+ db.executeUpdateSql("truncate table snapshot_sources");
+ db.executeUpdateSql("truncate table projects");
+ db.executeUpdateSql("truncate table project_measures");
+ db.executeUpdateSql("truncate table file_sources");
+
+ system = mock(System2.class);
+ when(system.now()).thenReturn(NOW);
+ migration = new FeedFileSources(db.database(), system);
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate_sources_with_no_scm_no_coverage() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ db.executeUpdateSql("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')");
+
+ db.executeUpdateSql("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(7, '', '2014-10-31 16:44:02.000')");
+
+ migration.execute();
+
+ List<Map<String, Object>> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " +
+ "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources");
+ assertThat(results).hasSize(2);
+
+ assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject");
+ assertThat(results.get(0).get("fileUuid")).isEqualTo("uuid-Migrated.xoo");
+ assertThat(results.get(0).get("data")).isEqualTo("");
+ assertThat(results.get(0).get("lineHashes")).isEqualTo("");
+ assertThat(results.get(0).get("dataHash")).isEqualTo("");
+ assertThat(results.get(0).get("updatedAt")).isEqualTo(NOW);
+ assertThat(results.get(0).get("createdAt")).isEqualTo(1416238020000L);
+
+ assertThat(results.get(1).get("projectUuid")).isEqualTo("uuid-MyProject");
+ assertThat(results.get(1).get("fileUuid")).isEqualTo("uuid-MyFile.xoo");
+ assertThat(results.get(1).get("data")).isEqualTo(",,,,,,,,,,,,,,,class Foo {\r\n,,,,,,,,,,,,,,, // Empty\r\n,,,,,,,,,,,,,,,}\r\n,,,,,,,,,,,,,,,\r\n");
+ assertThat(results.get(1).get("lineHashes")).isEqualTo("6a19ce786467960a3a9b0d26383a464a\naab2dbc5fdeaa80b050b1d049ede357c\ncbb184dd8e05c9709e5dcaedaa0495cf\n\n");
+ assertThat(results.get(1).get("dataHash")).isEqualTo("");
+ assertThat(formatLongDate((long) results.get(1).get("updatedAt")).toString()).startsWith("2014-10-31");
+ assertThat(results.get(1).get("createdAt")).isEqualTo(NOW);
+ }
+
+ @Test
+ public void migrate_sources_with_scm_and_coverage_in_text_value() throws Exception {
+ migrate_sources_with_scm_and_coverage_in("text_value");
+ }
+
+ @Test
+ public void migrate_sources_with_scm_and_coverage_in_measure_data() throws Exception {
+ migrate_sources_with_scm_and_coverage_in("measure_data");
+ }
+
+ private void migrate_sources_with_scm_and_coverage_in(String columnName) throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ Connection connection = null;
+ try {
+ connection = db.openConnection();
+
+ connection.prepareStatement("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')")
+ .executeUpdate();
+
+ db.executeUpdateSql("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(7, '', '2014-10-31 16:44:02.000')");
+
+ PreparedStatement revisionStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(1, 6, ?)");
+ revisionStmt.setBytes(1, "1=aef12a;2=abe465;3=afb789;4=afb789".getBytes(StandardCharsets.UTF_8));
+ revisionStmt.executeUpdate();
+
+ PreparedStatement authorStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(2, 6, ?)");
+ authorStmt.setBytes(1, "1=alice;2=bob;3=carol;4=carol".getBytes(StandardCharsets.UTF_8));
+ authorStmt.executeUpdate();
+
+ PreparedStatement dateStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(3, 6, ?)");
+ dateStmt.setBytes(1, "1=2014-04-25T12:34:56+0100;2=2014-07-25T12:34:56+0100;3=2014-03-23T12:34:56+0100;4=2014-03-23T12:34:56+0100".getBytes(StandardCharsets.UTF_8));
+ dateStmt.executeUpdate();
+
+ PreparedStatement utHitsStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(4, 6, ?)");
+ utHitsStmt.setBytes(1, "1=1;3=0".getBytes(StandardCharsets.UTF_8));
+ utHitsStmt.executeUpdate();
+
+ PreparedStatement utCondStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(5, 6, ?)");
+ utCondStmt.setBytes(1, "1=4".getBytes(StandardCharsets.UTF_8));
+ utCondStmt.executeUpdate();
+
+ PreparedStatement utCoveredCondStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(6, 6, ?)");
+ utCoveredCondStmt.setBytes(1, "1=2".getBytes(StandardCharsets.UTF_8));
+ utCoveredCondStmt.executeUpdate();
+
+ PreparedStatement itHitsStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(7, 6, ?)");
+ itHitsStmt.setBytes(1, "1=2;3=0".getBytes(StandardCharsets.UTF_8));
+ itHitsStmt.executeUpdate();
+
+ PreparedStatement itCondStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(8, 6, ?)");
+ itCondStmt.setBytes(1, "1=5".getBytes(StandardCharsets.UTF_8));
+ itCondStmt.executeUpdate();
+
+ PreparedStatement itCoveredCondStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(9, 6, ?)");
+ itCoveredCondStmt.setBytes(1, "1=3".getBytes(StandardCharsets.UTF_8));
+ itCoveredCondStmt.executeUpdate();
+
+ PreparedStatement overallHitsStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(10, 6, ?)");
+ overallHitsStmt.setBytes(1, "1=3;3=0".getBytes(StandardCharsets.UTF_8));
+ overallHitsStmt.executeUpdate();
+
+ PreparedStatement overallCondStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(11, 6, ?)");
+ overallCondStmt.setBytes(1, "1=6".getBytes(StandardCharsets.UTF_8));
+ overallCondStmt.executeUpdate();
+
+ PreparedStatement overallCoveredCondStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(12, 6, ?)");
+ overallCoveredCondStmt.setBytes(1, "1=4".getBytes(StandardCharsets.UTF_8));
+ overallCoveredCondStmt.executeUpdate();
+
+ PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, " + columnName + ") " +
+ "values " +
+ "(13, 6, ?)");
+ duplicationDataStmt
+ .setBytes(
+ 1,
+ "<duplications><g><b s=\"1\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"2\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"3\" l=\"1\" r=\"MyProject:src/main/xoo/prj/AnotherFile.xoo\"/></g></duplications>"
+ .getBytes(StandardCharsets.UTF_8));
+ duplicationDataStmt.executeUpdate();
+ } finally {
+ DbUtils.commitAndCloseQuietly(connection);
+ }
+
+ migration.execute();
+
+ List<Map<String, Object>> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " +
+ "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources");
+ assertThat(results).hasSize(2);
+
+ assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject");
+ assertThat(results.get(0).get("fileUuid")).isEqualTo("uuid-Migrated.xoo");
+ assertThat(results.get(0).get("data")).isEqualTo("");
+ assertThat(results.get(0).get("lineHashes")).isEqualTo("");
+ assertThat(results.get(0).get("dataHash")).isEqualTo("");
+ assertThat(results.get(0).get("updatedAt")).isEqualTo(NOW);
+ assertThat(results.get(0).get("createdAt")).isEqualTo(1416238020000L);
+
+ assertThat(results.get(1).get("projectUuid")).isEqualTo("uuid-MyProject");
+ assertThat(results.get(1).get("fileUuid")).isEqualTo("uuid-MyFile.xoo");
+ assertThat(results.get(1).get("data")).isEqualTo(
+ "aef12a,alice,2014-04-25T12:34:56+0100,1,4,2,2,5,3,3,6,4,,,1,class Foo {\r\nabe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,2, " +
+ "// Empty\r\nafb789,carol,2014-03-23T12:34:56+0100,0,,,0,,,0,,,,,,}\r\nafb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,,\r\n");
+ assertThat(results.get(1).get("lineHashes")).isEqualTo("6a19ce786467960a3a9b0d26383a464a\naab2dbc5fdeaa80b050b1d049ede357c\ncbb184dd8e05c9709e5dcaedaa0495cf\n\n");
+ assertThat(results.get(1).get("dataHash")).isEqualTo("");
+ assertThat(formatLongDate((long) results.get(1).get("updatedAt")).toString()).startsWith("2014-10-31");
+ assertThat(results.get(1).get("createdAt")).isEqualTo(NOW);
+ }
+
+ @Test
+ public void migrate_sources_with_invalid_duplication() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ Connection connection = null;
+ try {
+ connection = db.openConnection();
+
+ connection.prepareStatement("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')")
+ .executeUpdate();
+
+ db.executeUpdateSql("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(7, '', '2014-10-31 16:44:02.000')");
+
+ PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, text_value) " +
+ "values " +
+ "(13, 6, ?)");
+ duplicationDataStmt
+ .setBytes(
+ 1,
+ "<duplications><g><b s=\"1\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"2\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"3\" l=\"1\" r=\"MyProject:src/main/xoo/prj/AnotherFile.xoo\"/"
+ .getBytes(StandardCharsets.UTF_8));
+ duplicationDataStmt.executeUpdate();
+ } finally {
+ DbUtils.commitAndCloseQuietly(connection);
+ }
+
+ migration.execute();
+
+ // db.assertDbUnit(getClass(), "after-with-invalid-duplication.xml", "file_sources");
+
+ List<Map<String, Object>> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " +
+ "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources");
+ assertThat(results).hasSize(2);
+
+ assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject");
+ assertThat(results.get(0).get("fileUuid")).isEqualTo("uuid-Migrated.xoo");
+ assertThat(results.get(0).get("data")).isEqualTo("");
+ assertThat(results.get(0).get("lineHashes")).isEqualTo("");
+ assertThat(results.get(0).get("dataHash")).isEqualTo("");
+ assertThat(results.get(0).get("updatedAt")).isEqualTo(NOW);
+ assertThat(results.get(0).get("createdAt")).isEqualTo(1416238020000L);
+
+ assertThat(results.get(1).get("projectUuid")).isEqualTo("uuid-MyProject");
+ assertThat(results.get(1).get("fileUuid")).isEqualTo("uuid-MyFile.xoo");
+ assertThat(results.get(1).get("data")).isEqualTo(",,,,,,,,,,,,,,,class Foo {\r\n,,,,,,,,,,,,,,, // Empty\r\n,,,,,,,,,,,,,,,}\r\n,,,,,,,,,,,,,,,\r\n");
+ assertThat(results.get(1).get("lineHashes")).isEqualTo("6a19ce786467960a3a9b0d26383a464a\naab2dbc5fdeaa80b050b1d049ede357c\ncbb184dd8e05c9709e5dcaedaa0495cf\n\n");
+ assertThat(results.get(1).get("dataHash")).isEqualTo("");
+ assertThat(formatLongDate((long) results.get(1).get("updatedAt")).toString()).startsWith("2014-10-31");
+ assertThat(results.get(1).get("createdAt")).isEqualTo(NOW);
+ }
+
+ private String formatLongDate(long dateInMs) {
+ return DateUtils.formatDateTime(DateUtils.longToDate(dateInMs));
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java
new file mode 100644
index 00000000000..5969a262803
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedIssueLongDatesTest.java
@@ -0,0 +1,51 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v50;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedIssueLongDatesTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueLongDatesTest.class, "schema.sql");
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ System2 system = mock(System2.class);
+ when(system.now()).thenReturn(1500000000000L);
+ MigrationStep migration = new FeedIssueLongDates(db.database(), system);
+ migration.execute();
+
+ int count = db.countSql("select count(*) from issues where created_at_ms is not null and updated_at_ms is not null");
+ assertThat(count).isEqualTo(3);
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java
new file mode 100644
index 00000000000..ebb137512cd
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FileSourceDtoTest.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v50;
+
+import org.junit.Test;
+import org.sonar.db.version.v50.FileSourceDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class FileSourceDtoTest {
+
+ @Test
+ public void checksumOfBlankLine() {
+ assertThat(FileSourceDto.lineChecksum("")).isEmpty();
+ assertThat(FileSourceDto.lineChecksum(" \r\n")).isEmpty();
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java
new file mode 100644
index 00000000000..4226635344a
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v50;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class InsertProjectsAuthorizationUpdatedAtMigrationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, InsertProjectsAuthorizationUpdatedAtMigrationTest.class, "schema.sql");
+
+ MigrationStep migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table projects");
+ migration = new InsertProjectsAuthorizationUpdatedAtMigrationStep(db.database(), system);
+ when(system.now()).thenReturn(123456789L);
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "after.xml", "projects");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java
new file mode 100644
index 00000000000..4de215aae6f
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest.java
@@ -0,0 +1,324 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v50;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateProjectsUuidColumnsMigrationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, PopulateProjectsUuidColumnsMigrationTest.class, "schema.sql");
+
+ DbClient dbClient = db.getDbClient();
+
+ Migration50Mapper mapper;
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table projects");
+ db.executeUpdateSql("truncate table snapshots");
+ mapper = db.getSession().getMapper(Migration50Mapper.class);
+ migration = new PopulateProjectsUuidColumnsMigrationStep(dbClient);
+ }
+
+ @Test
+ public void migrate_components() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_components.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isNotNull();
+ assertThat(module.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(module.getModuleUuid()).isEqualTo(root.getUuid());
+ assertThat(module.getModuleUuidPath()).isEqualTo(root.getUuid());
+
+ Component subModule = mapper.selectComponentByKey("org.struts:struts-db");
+ assertThat(subModule.getUuid()).isNotNull();
+ assertThat(subModule.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(subModule.getModuleUuid()).isEqualTo(module.getUuid());
+ assertThat(subModule.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid());
+
+ Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts");
+ assertThat(directory.getUuid()).isNotNull();
+ assertThat(directory.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(directory.getModuleUuid()).isEqualTo(subModule.getUuid());
+ assertThat(directory.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + "." + subModule.getUuid());
+
+ Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(file.getUuid()).isNotNull();
+ assertThat(file.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(file.getModuleUuid()).isEqualTo(subModule.getUuid());
+ assertThat(file.getModuleUuidPath()).isEqualTo(root.getUuid() + "." + module.getUuid() + "." + subModule.getUuid());
+
+ // Verify that each generated uuid is unique
+ assertThat(ImmutableSet.of(root.getUuid(), module.getUuid(), subModule.getUuid(), directory.getUuid(), file.getUuid())).hasSize(5);
+ }
+
+ @Test
+ public void not_migrate_already_migrated_components() throws Exception {
+ db.prepareDbUnit(getClass(), "not_migrate_already_migrated_components.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isEqualTo("ABCD");
+ assertThat(root.getProjectUuid()).isEqualTo("ABCD");
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isEqualTo("BCDE");
+ assertThat(module.getProjectUuid()).isEqualTo("ABCD");
+ assertThat(module.getModuleUuid()).isEqualTo("ABCD");
+ assertThat(module.getModuleUuidPath()).isEqualTo("ABCD");
+
+ Component subModule = mapper.selectComponentByKey("org.struts:struts-db");
+ assertThat(subModule.getUuid()).isNotNull();
+ assertThat(subModule.getProjectUuid()).isEqualTo("ABCD");
+ assertThat(subModule.getModuleUuid()).isEqualTo("BCDE");
+ assertThat(subModule.getModuleUuidPath()).isEqualTo("ABCD.BCDE");
+
+ Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts");
+ assertThat(directory.getUuid()).isNotNull();
+ assertThat(directory.getProjectUuid()).isEqualTo("ABCD");
+ assertThat(directory.getModuleUuid()).isEqualTo(subModule.getUuid());
+ assertThat(directory.getModuleUuidPath()).isEqualTo("ABCD.BCDE." + subModule.getUuid());
+
+ Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(file.getUuid()).isNotNull();
+ assertThat(file.getProjectUuid()).isEqualTo("ABCD");
+ assertThat(file.getModuleUuid()).isEqualTo(subModule.getUuid());
+ assertThat(file.getModuleUuidPath()).isEqualTo("ABCD.BCDE." + subModule.getUuid());
+
+ Component removedFile = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext2.java");
+ assertThat(removedFile.getUuid()).isEqualTo("DCBA");
+ assertThat(removedFile.getProjectUuid()).isEqualTo("ABCD");
+ assertThat(removedFile.getModuleUuid()).isEqualTo("BCDE");
+ assertThat(removedFile.getModuleUuidPath()).isEqualTo("ABCD.BCDE");
+ }
+
+ @Test
+ public void migrate_disable_components() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_disable_components.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isNotNull();
+ assertThat(module.getProjectUuid()).isEqualTo(root.getUuid());
+ // Module and module path will always be null for removed components
+ assertThat(module.getModuleUuid()).isNull();
+ assertThat(module.getModuleUuidPath()).isEmpty();
+
+ Component subModule = mapper.selectComponentByKey("org.struts:struts-db");
+ assertThat(subModule.getUuid()).isNotNull();
+ assertThat(subModule.getProjectUuid()).isEqualTo(root.getUuid());
+ // Module and module path will always be null for removed components
+ assertThat(subModule.getModuleUuid()).isNull();
+ assertThat(subModule.getModuleUuidPath()).isEmpty();
+
+ Component directory = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts");
+ assertThat(directory.getUuid()).isNotNull();
+ assertThat(directory.getProjectUuid()).isEqualTo(root.getUuid());
+ // Module and module path will always be null for removed components
+ assertThat(directory.getModuleUuid()).isNull();
+ assertThat(directory.getModuleUuidPath()).isEmpty();
+
+ Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(file.getUuid()).isNotNull();
+ assertThat(file.getProjectUuid()).isEqualTo(root.getUuid());
+ // Module and module path will always be null for removed components
+ assertThat(file.getModuleUuid()).isNull();
+ assertThat(file.getModuleUuidPath()).isEmpty();
+ }
+
+ @Test
+ public void migrate_provisioned_project() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_provisioned_project.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+ }
+
+ @Test
+ public void migrate_library() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_library.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component root = mapper.selectComponentByKey("org.hamcrest:hamcrest-library");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+ }
+
+ @Test
+ public void migrate_view() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_view.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component view = mapper.selectComponentByKey("view");
+ assertThat(view.getUuid()).isNotNull();
+ assertThat(view.getProjectUuid()).isEqualTo(view.getUuid());
+ assertThat(view.getModuleUuid()).isNull();
+ assertThat(view.getModuleUuidPath()).isEmpty();
+
+ Component subView = mapper.selectComponentByKey("subView");
+ assertThat(subView.getUuid()).isNotNull();
+ assertThat(subView.getProjectUuid()).isEqualTo(view.getUuid());
+ assertThat(subView.getModuleUuid()).isEqualTo(view.getUuid());
+ assertThat(subView.getModuleUuidPath()).isEqualTo(view.getUuid());
+
+ Component techProject = mapper.selectComponentByKey("vieworg.struts:struts");
+ assertThat(techProject.getUuid()).isNotNull();
+ assertThat(techProject.getProjectUuid()).isEqualTo(view.getUuid());
+ assertThat(techProject.getModuleUuid()).isEqualTo(subView.getUuid());
+ assertThat(techProject.getModuleUuidPath()).isEqualTo(view.getUuid() + "." + subView.getUuid());
+ }
+
+ @Test
+ public void migrate_developer() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_developer.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ Component dev = mapper.selectComponentByKey("DEV:developer@company.net");
+ assertThat(dev.getUuid()).isNotNull();
+ assertThat(dev.getProjectUuid()).isEqualTo(dev.getUuid());
+ assertThat(dev.getModuleUuid()).isNull();
+ assertThat(dev.getModuleUuidPath()).isEmpty();
+
+ Component techDev = mapper.selectComponentByKey("DEV:developer@company.net:org.struts:struts");
+ assertThat(techDev.getUuid()).isNotNull();
+ assertThat(techDev.getProjectUuid()).isEqualTo(dev.getUuid());
+ assertThat(techDev.getModuleUuid()).isEqualTo(dev.getUuid());
+ assertThat(techDev.getModuleUuidPath()).isEqualTo(dev.getUuid());
+ }
+
+ @Test
+ public void migrate_components_without_uuid() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate_components_without_uuid.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ // Root project migrated
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+
+ // Module with a snapshot having no islast=true
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isNotNull();
+ assertThat(module.getProjectUuid()).isEqualTo(module.getUuid());
+ assertThat(module.getModuleUuid()).isNull();
+ assertThat(module.getModuleUuidPath()).isEmpty();
+
+ // File linked on a no more existing project
+ Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
+ assertThat(file.getUuid()).isNotNull();
+ assertThat(file.getProjectUuid()).isEqualTo(file.getUuid());
+ assertThat(file.getModuleUuid()).isNull();
+ assertThat(file.getModuleUuidPath()).isEmpty();
+ }
+
+ @Test
+ public void not_fail_when_module_has_no_root_id() throws Exception {
+ db.prepareDbUnit(getClass(), "not_fail_when_module_has_no_root_id.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ // Root project migrated
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+
+ // The module without uuid will be migrated as a standalone component
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isNotNull();
+ assertThat(module.getProjectUuid()).isEqualTo(module.getUuid());
+ assertThat(module.getModuleUuid()).isNull();
+ assertThat(module.getModuleUuidPath()).isEmpty();
+ }
+
+ @Test
+ public void not_fail_when_project_has_two_active_snapshots() throws Exception {
+ db.prepareDbUnit(getClass(), "not_fail_when_project_has_two_active_snapshots.xml");
+
+ migration.execute();
+ db.getSession().commit();
+
+ // Root project migrated
+ Component root = mapper.selectComponentByKey("org.struts:struts");
+ assertThat(root.getUuid()).isNotNull();
+ assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+ assertThat(root.getModuleUuid()).isNull();
+ assertThat(root.getModuleUuidPath()).isEmpty();
+
+ // The module linked on second active snapshot should be migrated a standalone component
+ Component module = mapper.selectComponentByKey("org.struts:struts-core");
+ assertThat(module.getUuid()).isNotNull();
+ assertThat(module.getProjectUuid()).isEqualTo(module.getUuid());
+ assertThat(module.getModuleUuid()).isNull();
+ assertThat(module.getModuleUuidPath()).isEmpty();
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java
new file mode 100644
index 00000000000..bf96e3af226
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest.java
@@ -0,0 +1,56 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v50;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RemoveSortFieldFromIssueFiltersMigrationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveSortFieldFromIssueFiltersMigrationTest.class, "schema.sql");
+
+ MigrationStep migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table issue_filters");
+ migration = new RemoveSortFieldFromIssueFiltersMigrationStep(db.database(), system);
+ when(system.now()).thenReturn(DateUtils.parseDate("2014-10-29").getTime());
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "execute.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "execute-result.xml", "issue_filters");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java
new file mode 100644
index 00000000000..e51c5fd2b32
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest.java
@@ -0,0 +1,66 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v50;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ReplaceIssueFiltersProjectKeyByUuidTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, ReplaceIssueFiltersProjectKeyByUuidTest.class, "schema.sql");
+
+ MigrationStep migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table issue_filters");
+ migration = new ReplaceIssueFiltersProjectKeyByUuid(db.database(), system);
+ when(system.now()).thenReturn(DateUtils.parseDate("2014-10-29").getTime());
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "execute.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "execute-result.xml", "issue_filters");
+ }
+
+ @Test
+ public void do_not_execute_if_already_migrated() throws Exception {
+ db.prepareDbUnit(getClass(), "do_not_execute_if_already_migrated.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "do_not_execute_if_already_migrated-result.xml", "issue_filters");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java
new file mode 100644
index 00000000000..40683d1ebb4
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/AddIssuesColumnsTest.java
@@ -0,0 +1,54 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import java.sql.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class AddIssuesColumnsTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddIssuesColumnsTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ migration = new AddIssuesColumns(db.database());
+ }
+
+ @Test
+ public void update_columns() throws Exception {
+ migration.execute();
+
+ db.assertColumnDefinition("issues", "issue_creation_date_ms", Types.BIGINT, null);
+ db.assertColumnDefinition("issues", "issue_update_date_ms", Types.BIGINT, null);
+ db.assertColumnDefinition("issues", "issue_close_date_ms", Types.BIGINT, null);
+ db.assertColumnDefinition("issues", "tags", Types.VARCHAR, 4000);
+ db.assertColumnDefinition("issues", "component_uuid", Types.VARCHAR, 50);
+ db.assertColumnDefinition("issues", "project_uuid", Types.VARCHAR, 50);
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java
new file mode 100644
index 00000000000..cfc43d2246d
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/AddNewCharacteristicsTest.java
@@ -0,0 +1,138 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static junit.framework.TestCase.fail;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AddNewCharacteristicsTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddNewCharacteristicsTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table characteristics");
+
+ when(system.now()).thenReturn(DateUtils.parseDate("2015-02-15").getTime());
+
+ migration = new AddNewCharacteristics(db.database(), system);
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(getClass(), "migrate-result.xml", "characteristics");
+ }
+
+ @Test
+ public void do_nothing_when_already_migrated() throws Exception {
+ db.prepareDbUnit(getClass(), "do_nothing_when_already_migrated.xml");
+ migration.execute();
+ db.assertDbUnit(getClass(), "do_nothing_when_already_migrated.xml", "characteristics");
+ }
+
+ @Test
+ public void do_nothing_when_no_characteristics() throws Exception {
+ db.prepareDbUnit(getClass(), "empty.xml");
+ migration.execute();
+ assertThat(db.countRowsOfTable("characteristics")).isEqualTo(0);
+ }
+
+ @Test
+ public void insert_usability_at_the_top_if_security_does_exists() throws Exception {
+ db.prepareDbUnit(getClass(), "insert_usability_at_the_top_if_security_does_exists.xml");
+ migration.execute();
+ db.assertDbUnit(getClass(), "insert_usability_at_the_top_if_security_does_exists-result.xml", "characteristics");
+ }
+
+ @Test
+ public void update_usability_order_if_already_exists() throws Exception {
+ db.prepareDbUnit(getClass(), "update_usability_if_already_exists.xml");
+ migration.execute();
+ db.assertDbUnit(getClass(), "update_usability_if_already_exists-result.xml", "characteristics");
+ }
+
+ @Test
+ public void fail_if_usability_exists_as_sub_characteristic() {
+ db.prepareDbUnit(getClass(), "fail_if_usability_exists_as_sub_characteristic.xml");
+
+ try {
+ migration.execute();
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(MessageException.class).hasMessage(
+ "'Usability' must be a characteristic. Please restore your DB backup, start the previous version of SonarQube " +
+ "and update your SQALE model to fix this issue before trying again to run the migration.");
+ }
+ }
+
+ @Test
+ public void fail_if_compliance_already_exists_as_characteristic() {
+ db.prepareDbUnit(getClass(), "fail_if_compliance_already_exists_as_characteristic.xml");
+
+ try {
+ migration.execute();
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(MessageException.class).hasMessage(
+ "'Compliance' must be a sub-characteristic. Please restore your DB backup, start the previous version of SonarQube " +
+ "and update your SQALE model to fix this issue before trying again to run the migration.");
+ }
+ }
+
+ @Test
+ public void fail_if_compliance_already_exists_under_wrong_characteristic() {
+ db.prepareDbUnit(getClass(), "fail_if_compliance_already_exists_under_wrong_characteristic.xml");
+
+ try {
+ migration.execute();
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(MessageException.class).hasMessage(
+ "'Reusability Compliance' must be defined under 'Reusability'. Please restore your DB backup, start the previous version of SonarQube " +
+ "and update your SQALE model to fix this issue before trying again to run the migration.");
+ }
+ }
+
+ @Test
+ public void not_fail_if_some_deprecated_requirements_still_exists_in_db() throws Exception {
+ db.prepareDbUnit(getClass(), "not_fail_if_some_deprecated_requirements_still_exists_in_db.xml");
+ migration.execute();
+ db.assertDbUnit(getClass(), "not_fail_if_some_deprecated_requirements_still_exists_in_db.xml", "characteristics");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java
new file mode 100644
index 00000000000..c0345ad2862
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest.java
@@ -0,0 +1,102 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CopyScmAccountsFromAuthorsToUsersTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, CopyScmAccountsFromAuthorsToUsersTest.class, "schema.sql");
+
+ MigrationStep migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table authors");
+ db.executeUpdateSql("truncate table users");
+ migration = new CopyScmAccountsFromAuthorsToUsers(db.database(), system);
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+ Long oldDate = 1500000000000L;
+ Long updatedDate = 2000000000000L;
+ when(system.now()).thenReturn(updatedDate);
+
+ migration.execute();
+
+ User simon = getUserByLogin("simon");
+ assertThat(simon.scmAccounts).isEqualTo(UserDto.SCM_ACCOUNTS_SEPARATOR + "Simon B" + UserDto.SCM_ACCOUNTS_SEPARATOR + "simon@codehaus.org" + UserDto.SCM_ACCOUNTS_SEPARATOR);
+ assertThat(simon.updatedAt).isEqualTo(updatedDate);
+
+ User fabrice = getUserByLogin("fabrice");
+ assertThat(fabrice.scmAccounts).isEqualTo(UserDto.SCM_ACCOUNTS_SEPARATOR + "fab" + UserDto.SCM_ACCOUNTS_SEPARATOR);
+ assertThat(fabrice.updatedAt).isEqualTo(updatedDate);
+
+ assertThat(getUserByLogin("julien").updatedAt).isEqualTo(oldDate);
+ assertThat(getUserByLogin("jb").updatedAt).isEqualTo(oldDate);
+ assertThat(getUserByLogin("disable").updatedAt).isEqualTo(oldDate);
+ assertThat(getUserByLogin("teryk").updatedAt).isEqualTo(oldDate);
+ assertThat(getUserByLogin("teryk2").updatedAt).isEqualTo(oldDate);
+ }
+
+ @Test
+ public void nothing_to_migrate_when_no_authors() throws Exception {
+ db.prepareDbUnit(getClass(), "no_authors.xml");
+ Long oldDate = 1500000000000L;
+ Long updatedDate = 2000000000000L;
+ when(system.now()).thenReturn(updatedDate);
+
+ migration.execute();
+
+ assertThat(db.countSql("SELECT count(*) FROM USERS WHERE updated_at=" + updatedDate)).isEqualTo(0);
+ assertThat(db.countSql("SELECT count(*) FROM USERS WHERE updated_at=" + oldDate)).isEqualTo(7);
+ }
+
+ private User getUserByLogin(String login) {
+ return new User(db.selectFirst("SELECT u.scm_Accounts as \"scmAccounts\", u.updated_at as \"updatedAt\" FROM users u WHERE u.login='" + login + "'"));
+ }
+
+ private static class User {
+ String scmAccounts;
+ Long updatedAt;
+
+ User(Map<String, Object> map) {
+ scmAccounts = (String) map.get("scmAccounts");
+ updatedAt = (Long) map.get("updatedAt");
+ }
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java
new file mode 100644
index 00000000000..3971e9c1838
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/DropIssuesColumnsTest.java
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.db.Database;
+import org.sonar.db.dialect.PostgreSql;
+import org.sonar.db.version.v51.DropIssuesColumns;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DropIssuesColumnsTest {
+
+ DropIssuesColumns migration;
+
+ Database database;
+
+ @Before
+ public void setUp() {
+ database = mock(Database.class);
+ migration = new DropIssuesColumns(database);
+ }
+
+ @Test
+ public void generate_sql_on_postgresql() {
+ when(database.getDialect()).thenReturn(new PostgreSql());
+ assertThat(migration.generateSql()).isEqualTo(
+ "ALTER TABLE issues DROP COLUMN issue_creation_date, DROP COLUMN issue_update_date, DROP COLUMN issue_close_date, DROP COLUMN component_id, DROP COLUMN root_component_id"
+ );
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java
new file mode 100644
index 00000000000..c3e75f1fc75
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest.java
@@ -0,0 +1,53 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedAnalysisReportsLongDatesTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedAnalysisReportsLongDatesTest.class, "schema.sql");
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ System2 system = mock(System2.class);
+ when(system.now()).thenReturn(1500000000000L);
+ MigrationStep migration = new FeedAnalysisReportsLongDates(db.database(), system);
+ migration.execute();
+
+ int count = db.countSql("select count(*) from analysis_reports where created_at_ms is not null and updated_at_ms is not null");
+ assertThat(count).isEqualTo(3);
+
+ int countWithAllDateFieldsNull = db
+ .countSql("select count(*) from analysis_reports where created_at_ms is not null and updated_at_ms is not null and started_at_ms is not null and finished_at_ms is not null");
+ assertThat(countWithAllDateFieldsNull).isEqualTo(2);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java
new file mode 100644
index 00000000000..96104aee886
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedEventsLongDatesTest.java
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.parseDate;
+
+public class FeedEventsLongDatesTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedEventsLongDatesTest.class, "schema.sql");
+
+ @Before
+ public void before() {
+ db.prepareDbUnit(getClass(), "before.xml");
+ }
+
+ @Test
+ public void execute() throws Exception {
+ MigrationStep migration = newMigration(System2.INSTANCE);
+
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from events where " +
+ "created_at_ms is not null " +
+ "and event_date_ms is not null");
+ assertThat(count).isEqualTo(3);
+ }
+
+ @Test
+ public void take_now_if_date_in_the_future() throws Exception {
+ System2 system = mock(System2.class);
+ when(system.now()).thenReturn(1234L);
+
+ MigrationStep migration = newMigration(system);
+
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from events where " +
+ "created_at_ms = 1234");
+ assertThat(count).isEqualTo(2);
+ }
+
+ @Test
+ public void take_date_if_in_the_past() throws Exception {
+ MigrationStep migration = newMigration(System2.INSTANCE);
+
+ migration.execute();
+
+ long time = parseDate("2014-09-25").getTime();
+ int count = db
+ .countSql("select count(*) from events where " +
+ "created_at_ms=" + time);
+ assertThat(count).isEqualTo(1);
+ }
+
+ private MigrationStep newMigration(System2 system) {
+ return new FeedEventsLongDates(db.database(), system);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java
new file mode 100644
index 00000000000..2bf3bc23004
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest.java
@@ -0,0 +1,97 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import org.apache.commons.dbutils.DbUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.source.FileSourceDto;
+import org.sonar.db.version.MigrationStep;
+import org.sonar.server.source.db.FileSourceDb;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class FeedFileSourcesBinaryDataTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedFileSourcesBinaryDataTest.class, "schema.sql");
+
+ @Test
+ public void convert_csv_to_protobuf() throws Exception {
+ db.prepareDbUnit(getClass(), "data.xml");
+
+ MigrationStep migration = new FeedFileSourcesBinaryData(db.database());
+ migration.execute();
+
+ int count = db.countSql("select count(*) from file_sources where binary_data is not null");
+ assertThat(count).isEqualTo(3);
+
+ try (Connection connection = db.openConnection()) {
+ FileSourceDb.Data data = selectData(connection, 1L);
+ assertThat(data.getLinesCount()).isEqualTo(4);
+ assertThat(data.getLines(0).getScmRevision()).isEqualTo("aef12a");
+
+ data = selectData(connection, 2L);
+ assertThat(data.getLinesCount()).isEqualTo(4);
+ assertThat(data.getLines(0).hasScmRevision()).isFalse();
+
+ data = selectData(connection, 3L);
+ assertThat(data.getLinesCount()).isEqualTo(0);
+ }
+ }
+
+ @Test
+ public void fail_to_parse_csv() throws Exception {
+ db.prepareDbUnit(getClass(), "bad_data.xml");
+
+ MigrationStep migration = new FeedFileSourcesBinaryData(db.database());
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=1,data=");
+
+ migration.execute();
+ }
+
+ private FileSourceDb.Data selectData(Connection connection, long fileSourceId) throws SQLException {
+ PreparedStatement pstmt = connection.prepareStatement("select binary_data from file_sources where id=?");
+ ResultSet rs = null;
+ try {
+ pstmt.setLong(1, fileSourceId);
+ rs = pstmt.executeQuery();
+ rs.next();
+ InputStream data = rs.getBinaryStream(1);
+ return FileSourceDto.decodeSourceData(data);
+ } finally {
+ DbUtils.closeQuietly(rs);
+ DbUtils.closeQuietly(pstmt);
+ }
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java
new file mode 100644
index 00000000000..01690ce52df
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest.java
@@ -0,0 +1,53 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedIssueChangesLongDatesTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueChangesLongDatesTest.class, "schema.sql");
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ System2 system = mock(System2.class);
+ when(system.now()).thenReturn(1500000000000L);
+ MigrationStep migration = new FeedIssueChangesLongDates(db.database(), system);
+ migration.execute();
+
+ int count = db.countSql("select count(*) from issue_changes where created_at_ms is not null and updated_at_ms is not null");
+ assertThat(count).isEqualTo(3);
+
+ int countWithAllDateFieldsNull = db
+ .countSql("select count(*) from issue_changes where created_at_ms is not null and updated_at_ms is not null and issue_change_creation_date_ms is not null");
+ assertThat(countWithAllDateFieldsNull).isEqualTo(2);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java
new file mode 100644
index 00000000000..de5f1c94c05
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueComponentUuidsTest.java
@@ -0,0 +1,53 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+public class FeedIssueComponentUuidsTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueComponentUuidsTest.class, "schema.sql");
+
+ FeedIssueComponentUuids underTest;
+
+ @Before
+ public void setUp() {
+ db.truncateTables();
+
+ underTest = new FeedIssueComponentUuids(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ underTest.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "before.xml");
+ underTest.execute();
+ db.assertDbUnit(this.getClass(), "after-result.xml", "issues");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java
new file mode 100644
index 00000000000..1e630545f94
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssueTagsTest.java
@@ -0,0 +1,64 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import java.util.Date;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedIssueTagsTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssueTagsTest.class, "schema.sql");
+
+ FeedIssueTags migration;
+
+ System2 system;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table rules");
+ db.executeUpdateSql("truncate table issues");
+
+ system = mock(System2.class);
+ Date now = DateUtils.parseDateTime("2014-12-08T17:33:00+0100");
+ when(system.now()).thenReturn(now.getTime());
+ migration = new FeedIssueTags(db.database(), system);
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate_with_rule_tags() throws Exception {
+ db.prepareDbUnit(this.getClass(), "before.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "after-result.xml", "issues");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java
new file mode 100644
index 00000000000..b10df31cb5d
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedIssuesLongDatesTest.java
@@ -0,0 +1,81 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.parseDate;
+
+public class FeedIssuesLongDatesTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedIssuesLongDatesTest.class, "schema.sql");
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ MigrationStep migration = new FeedIssuesLongDates(db.database(), System2.INSTANCE);
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from issues where " +
+ "issue_creation_date_ms is not null " +
+ "and issue_update_date_ms is not null " +
+ "and issue_close_date_ms is not null");
+ assertThat(count).isEqualTo(2);
+ }
+
+ @Test
+ public void take_now_if_date_in_the_future() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+ System2 system2 = mock(System2.class);
+ when(system2.now()).thenReturn(0L);
+
+ MigrationStep migration = new FeedIssuesLongDates(db.database(), mock(System2.class));
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from issues where " +
+ "issue_creation_date_ms = 0");
+ assertThat(count).isEqualTo(1);
+ }
+
+ @Test
+ public void take_snapshot_date_if_in_the_past() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+ long snapshotTime = parseDate("2014-09-25").getTime();
+
+ MigrationStep migration = new FeedIssuesLongDates(db.database(), System2.INSTANCE);
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from issues where " +
+ "issue_creation_date_ms=" + snapshotTime);
+ assertThat(count).isEqualTo(1);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java
new file mode 100644
index 00000000000..2b4f3f5facb
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest.java
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.parseDate;
+
+public class FeedManualMeasuresLongDatesTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedManualMeasuresLongDatesTest.class, "schema.sql");
+
+ @Before
+ public void before() {
+ db.prepareDbUnit(getClass(), "before.xml");
+ }
+
+ @Test
+ public void execute() throws Exception {
+ MigrationStep migration = newMigration(System2.INSTANCE);
+
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from manual_measures where " +
+ "created_at_ms is not null " +
+ "and updated_at_ms is not null");
+ assertThat(count).isEqualTo(2);
+ }
+
+ @Test
+ public void take_now_if_date_in_the_future() throws Exception {
+ System2 system = mock(System2.class);
+ when(system.now()).thenReturn(1234L);
+
+ MigrationStep migration = newMigration(system);
+
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from manual_measures where " +
+ "created_at_ms = 1234");
+ assertThat(count).isEqualTo(1);
+ }
+
+ @Test
+ public void take_manual_measure_date_if_in_the_past() throws Exception {
+ MigrationStep migration = newMigration(System2.INSTANCE);
+
+ migration.execute();
+
+ long snapshotTime = parseDate("2014-09-25").getTime();
+ int count = db
+ .countSql("select count(*) from manual_measures where " +
+ "created_at_ms=" + snapshotTime);
+ assertThat(count).isEqualTo(1);
+ }
+
+ private MigrationStep newMigration(System2 system) {
+ return new FeedManualMeasuresLongDates(db.database(), system);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java
new file mode 100644
index 00000000000..8eeb8bb588b
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.parseDate;
+
+public class FeedSnapshotsLongDatesTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedSnapshotsLongDatesTest.class, "schema.sql");
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ MigrationStep migration = new FeedSnapshotsLongDates(db.database(), System2.INSTANCE);
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from snapshots where created_at_ms is not null " +
+ "and build_date_ms is not null " +
+ "and period1_date_ms is not null " +
+ "and period2_date_ms is not null " +
+ "and period3_date_ms is not null " +
+ "and period4_date_ms is not null " +
+ "and period5_date_ms is not null");
+ assertThat(count).isEqualTo(2);
+ }
+
+ @Test
+ public void take_now_if_date_in_the_future() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+ System2 system2 = mock(System2.class);
+ when(system2.now()).thenReturn(0L);
+
+ MigrationStep migration = new FeedSnapshotsLongDates(db.database(), mock(System2.class));
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from snapshots where " +
+ "created_at_ms = 0");
+ assertThat(count).isEqualTo(1);
+ }
+
+ @Test
+ public void take_snapshot_date_if_in_the_past() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+ long snapshotTime = parseDate("2014-09-25").getTime();
+
+ MigrationStep migration = new FeedSnapshotsLongDates(db.database(), System2.INSTANCE);
+ migration.execute();
+
+ int count = db
+ .countSql("select count(*) from snapshots where " +
+ "created_at_ms=" + snapshotTime);
+ assertThat(count).isEqualTo(1);
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java
new file mode 100644
index 00000000000..88923fbcb6e
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/FeedUsersLongDatesTest.java
@@ -0,0 +1,51 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedUsersLongDatesTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedUsersLongDatesTest.class, "schema.sql");
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ System2 system = mock(System2.class);
+ when(system.now()).thenReturn(1500000000000L);
+ MigrationStep migration = new FeedUsersLongDates(db.database(), system);
+ migration.execute();
+
+ int count = db.countSql("select count(*) from users where created_at_ms is not null and updated_at_ms is not null");
+ assertThat(count).isEqualTo(3);
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java
new file mode 100644
index 00000000000..3b41af6846e
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest.java
@@ -0,0 +1,59 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class RemovePermissionsOnModulesMigrationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemovePermissionsOnModulesMigrationTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ migration = new RemovePermissionsOnModulesMigrationStep(db.database());
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "migrate.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "migrate-result.xml", "user_roles", "group_roles");
+ }
+
+ @Test
+ public void nothing_to_do_when_already_migrated() throws Exception {
+ db.prepareDbUnit(getClass(), "nothing_to_do_when_already_migrated.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "nothing_to_do_when_already_migrated.xml", "user_roles", "group_roles");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java
new file mode 100644
index 00000000000..b2ecde9fa88
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest.java
@@ -0,0 +1,56 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RenameComponentRelatedParamsInIssueFiltersMigrationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, RenameComponentRelatedParamsInIssueFiltersMigrationTest.class, "schema.sql");
+
+ MigrationStep migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table issue_filters");
+ migration = new RenameComponentRelatedParamsInIssueFilters(db.database(), system);
+ when(system.now()).thenReturn(DateUtils.parseDate("2014-10-29").getTime());
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "execute.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "execute-result.xml", "issue_filters");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java b/sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java
new file mode 100644
index 00000000000..89a8d7e6c7d
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest.java
@@ -0,0 +1,65 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v51;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class UpdateProjectsModuleUuidPathTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, UpdateProjectsModuleUuidPathTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ System2 system;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table projects");
+
+ migration = new UpdateProjectsModuleUuidPath(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate_components.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate_components-result.xml", "projects");
+ }
+
+ @Test
+ public void not_migrate_already_migrated_components() throws Exception {
+ db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_components.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_components.xml", "projects");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java
new file mode 100644
index 00000000000..07f48d9a144
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest.java
@@ -0,0 +1,49 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import java.sql.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+public class AddManualMeasuresComponentUuidColumnTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, AddManualMeasuresComponentUuidColumnTest.class, "schema.sql");
+
+ AddManualMeasuresComponentUuidColumn underTest;
+
+ @Before
+ public void setUp() {
+ underTest = new AddManualMeasuresComponentUuidColumn(db.database());
+ }
+
+ @Test
+ public void update_columns() throws Exception {
+ underTest.execute();
+
+ db.assertColumnDefinition("manual_measures", "component_uuid", Types.VARCHAR, 50);
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java
new file mode 100644
index 00000000000..87f156d39be
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedEventsComponentUuidTest.java
@@ -0,0 +1,64 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class FeedEventsComponentUuidTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedEventsComponentUuidTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table events");
+ db.executeUpdateSql("truncate table projects");
+
+ migration = new FeedEventsComponentUuid(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "events");
+ }
+
+ @Test
+ public void not_migrate_already_migrated_data() throws Exception {
+ db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml", "events");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java
new file mode 100644
index 00000000000..615a41ba117
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest.java
@@ -0,0 +1,55 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class FeedFileSourcesDataTypeTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedFileSourcesDataTypeTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table file_sources");
+
+ migration = new FeedFileSourcesDataType(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "file_sources");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java
new file mode 100644
index 00000000000..cf76d6a4430
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest.java
@@ -0,0 +1,55 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+
+public class FeedManualMeasuresComponentUuidTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedManualMeasuresComponentUuidTest.class, "schema.sql");
+
+ FeedManualMeasuresComponentUuid underTest;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table manual_measures");
+ db.executeUpdateSql("truncate table projects");
+
+ underTest = new FeedManualMeasuresComponentUuid(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ underTest.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ underTest.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "manual_measures");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java
new file mode 100644
index 00000000000..b565f04dd34
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedMetricsBooleansTest.java
@@ -0,0 +1,54 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class FeedMetricsBooleansTest {
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedMetricsBooleansTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table metrics");
+
+ migration = new FeedMetricsBooleans(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "metrics");
+ }
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java
new file mode 100644
index 00000000000..4487d000614
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest.java
@@ -0,0 +1,63 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class FeedProjectLinksComponentUuidTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, FeedProjectLinksComponentUuidTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table project_links");
+
+ migration = new FeedProjectLinksComponentUuid(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "project_links");
+ }
+
+ @Test
+ public void not_migrate_already_migrated_data() throws Exception {
+ db.prepareDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "not_migrate_already_migrated_data.xml", "project_links");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java
new file mode 100644
index 00000000000..982859c34ae
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/MoveProjectProfileAssociationTest.java
@@ -0,0 +1,66 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class MoveProjectProfileAssociationTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, MoveProjectProfileAssociationTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table projects");
+ db.executeUpdateSql("truncate table project_qprofiles");
+ db.executeUpdateSql("truncate table properties");
+ db.executeUpdateSql("truncate table rules_profiles");
+
+ migration = new MoveProjectProfileAssociation(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "rules_profiles", "project_qprofiles");
+ }
+
+ @Test
+ public void not_migrate_already_migrated_data() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate-result.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "rules_profiles", "project_qprofiles");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java
new file mode 100644
index 00000000000..fa1d876f5af
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveComponentLibrariesTest.java
@@ -0,0 +1,56 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class RemoveComponentLibrariesTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveComponentLibrariesTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table projects");
+
+ migration = new RemoveComponentLibraries(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void remove_libraries() throws Exception {
+ db.prepareDbUnit(this.getClass(), "remove_libraries.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "remove_libraries-result.xml", "projects");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java
new file mode 100644
index 00000000000..79d5b1511ab
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java
@@ -0,0 +1,78 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class RemoveDuplicatedComponentKeysTest {
+
+ @ClassRule
+ public static DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveDuplicatedComponentKeysTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table projects");
+ db.executeUpdateSql("truncate table issues");
+
+ migration = new RemoveDuplicatedComponentKeys(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void migrate_components_and_issues() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "projects", "issues");
+ }
+
+ @Test
+ public void not_migrate_components_and_issues_already_migrated() throws Exception {
+ db.prepareDbUnit(this.getClass(), "migrate-result.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "migrate-result.xml", "projects", "issues");
+ }
+
+ @Test
+ public void keep_enable_component_when_enabled_component_exists() throws Exception {
+ db.prepareDbUnit(this.getClass(), "keep_enable_component.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "keep_enable_component-result.xml", "projects");
+ }
+
+ @Test
+ public void keep_last_component_when_no_enabled_components() throws Exception {
+ db.prepareDbUnit(this.getClass(), "keep_last_component.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "keep_last_component-result.xml", "projects");
+ }
+
+}
diff --git a/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java
new file mode 100644
index 00000000000..c9163a6c702
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest.java
@@ -0,0 +1,56 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.version.v52;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.version.MigrationStep;
+
+public class RemoveSnapshotLibrariesTest {
+
+ @Rule
+ public DbTester db = DbTester.createForSchema(System2.INSTANCE, RemoveSnapshotLibrariesTest.class, "schema.sql");
+
+ MigrationStep migration;
+
+ @Before
+ public void setUp() {
+ db.executeUpdateSql("truncate table snapshots");
+
+ migration = new RemoveSnapshotLibraries(db.database());
+ }
+
+ @Test
+ public void migrate_empty_db() throws Exception {
+ migration.execute();
+ }
+
+ @Test
+ public void remove_libraries() throws Exception {
+ db.prepareDbUnit(this.getClass(), "remove_libraries.xml");
+ migration.execute();
+ db.assertDbUnit(this.getClass(), "remove_libraries-result.xml", "snapshots");
+ }
+
+}
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml
new file mode 100644
index 00000000000..96ecbf4062f
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/batch-insert-result.xml
@@ -0,0 +1,8 @@
+<dataset>
+ <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/>
+ <persons id="2" login="emmerik" age="14" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/>
+ <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/>
+
+ <persons id="10" login="kurt" age="27" enabled="[true]" coeff="2.2" updated_at="[null]"/>
+ <persons id="11" login="courtney" age="25" enabled="[false]" coeff="2.3" updated_at="[null]"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml
new file mode 100644
index 00000000000..32b7ac03f06
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/insert-result.xml
@@ -0,0 +1,7 @@
+<dataset>
+ <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/>
+ <persons id="2" login="emmerik" age="14" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/>
+ <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/>
+
+ <persons id="10" login="kurt" age="27" enabled="[true]" coeff="2.2" updated_at="[null]"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml
new file mode 100644
index 00000000000..9eb2317febf
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/mass-update-result.xml
@@ -0,0 +1,5 @@
+<dataset>
+ <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/>
+ <persons id="2" login="login2" age="12" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/>
+ <persons id="3" login="login3" age="13" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml
new file mode 100644
index 00000000000..62c226d53b7
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/persons.xml
@@ -0,0 +1,5 @@
+<dataset>
+ <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/>
+ <persons id="2" login="emmerik" age="14" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/>
+ <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql
new file mode 100644
index 00000000000..499b25b599d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/schema.sql
@@ -0,0 +1,8 @@
+CREATE TABLE "PERSONS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "LOGIN" VARCHAR(50),
+ "AGE" INTEGER,
+ "ENABLED" BOOLEAN,
+ "UPDATED_AT" TIMESTAMP,
+ "COEFF" DOUBLE
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml
new file mode 100644
index 00000000000..0cf4e593d4d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/scroll-and-update-result.xml
@@ -0,0 +1,5 @@
+<dataset>
+ <persons id="1" login="login1" age="11" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/>
+ <persons id="2" login="login2" age="12" enabled="[true]" coeff="5.2" updated_at="2014-01-25"/>
+ <persons id="3" login="login3" age="13" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml
new file mode 100644
index 00000000000..ec48c899b40
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/BaseDataChangeTest/update-null-result.xml
@@ -0,0 +1,5 @@
+<dataset>
+ <persons id="1" login="barbara" age="56" enabled="[false]" coeff="1.5" updated_at="2014-01-25"/>
+ <persons id="2" login="[null]" age="[null]" enabled="[null]" coeff="[null]" updated_at="[null]"/>
+ <persons id="3" login="morgan" age="3" enabled="[true]" coeff="5.4" updated_at="2014-01-25"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml
new file mode 100644
index 00000000000..bb36c83c788
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/after.xml
@@ -0,0 +1,20 @@
+<dataset>
+ <!-- with default value -->
+ <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/>
+
+ <!-- without default value, to be ignored -->
+ <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]"/>
+
+ <!-- this active rule has all parameters -->
+ <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01"/>
+ <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+ <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+ <!-- this active rule does not have parameters. UPDATED_AT CHANGED -->
+ <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2014-04-28"/>
+
+ <!-- newly created -->
+ <active_rule_parameters id="10002" active_rule_id="101" rules_parameter_id="1" rules_parameter_key="max" value="10"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml
new file mode 100644
index 00000000000..df5d8fa0bbd
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/before.xml
@@ -0,0 +1,17 @@
+<dataset>
+ <!-- with default value -->
+ <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/>
+
+ <!-- without default value, to be ignored -->
+ <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]"/>
+
+ <!-- this active rule has all parameters -->
+ <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01"/>
+ <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+ <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+ <!-- this active rule does not have parameters -->
+ <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml
new file mode 100644
index 00000000000..fdd7750955e
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/no_changes.xml
@@ -0,0 +1,11 @@
+<dataset>
+ <!-- with default value -->
+ <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/>
+
+ <!-- this active rule has all parameters -->
+ <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01"/>
+ <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+ <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql
new file mode 100644
index 00000000000..ebb574482c3
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/AddMissingRuleParameterDefaultValuesMigrationTest/schema.sql
@@ -0,0 +1,28 @@
+CREATE TABLE "RULES_PARAMETERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "RULE_ID" INTEGER NOT NULL,
+ "NAME" VARCHAR(128) NOT NULL,
+ "PARAM_TYPE" VARCHAR(512) NOT NULL,
+ "DEFAULT_VALUE" VARCHAR(4000),
+ "DESCRIPTION" VARCHAR(4000)
+);
+
+
+CREATE TABLE "ACTIVE_RULES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROFILE_ID" INTEGER NOT NULL,
+ "RULE_ID" INTEGER NOT NULL,
+ "FAILURE_LEVEL" INTEGER NOT NULL,
+ "INHERITANCE" VARCHAR(10),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+
+CREATE TABLE "ACTIVE_RULE_PARAMETERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "ACTIVE_RULE_ID" INTEGER NOT NULL,
+ "RULES_PARAMETER_ID" INTEGER NOT NULL,
+ "RULES_PARAMETER_KEY" VARCHAR(128),
+ "VALUE" VARCHAR(4000)
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml
new file mode 100644
index 00000000000..14e559f4a12
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/before.xml
@@ -0,0 +1,34 @@
+<dataset>
+ <metrics id="1" name="quality_profiles" VAL_TYPE="DATA" DESCRIPTION="[null]" domain="[null]" short_name=""
+ enabled="[true]" worst_value="0" optimized_best_value="[true]" best_value="100" direction="1"
+ hidden="[false]" delete_historical_data="[null]"/>
+
+ <!-- old format, references a numeric value which is profile id -->
+ <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]"
+ url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
+ variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <!-- new format, json data -->
+ <project_measures id="2" VALUE="[null]" text_value="{json}" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]"
+ RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]"
+ url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
+ variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <!-- last snapshot -->
+ <snapshots purge_status="[null]" id="1001" project_id="1" parent_snapshot_id="[null]" root_project_id="1"
+ root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2009-11-01 13:58:00.00" build_date="2009-11-01 13:58:00.00"
+ version="[null]" path=""
+ status="P" islast="[true]" depth="0"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]"
+ period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]"
+ period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]"
+ period5_date="[null]"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql
new file mode 100644
index 00000000000..912fd080b0d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v45/DeleteMeasuresOnDeletedProfilesMigrationTest/schema.sql
@@ -0,0 +1,77 @@
+CREATE TABLE "PROJECT_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "VALUE" DOUBLE,
+ "METRIC_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "RULES_CATEGORY_ID" INTEGER,
+ "TEXT_VALUE" VARCHAR(4000),
+ "TENDENCY" INTEGER,
+ "MEASURE_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER,
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "URL" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(4000),
+ "RULE_PRIORITY" INTEGER,
+ "CHARACTERISTIC_ID" INTEGER,
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "VARIATION_VALUE_2" DOUBLE,
+ "VARIATION_VALUE_3" DOUBLE,
+ "VARIATION_VALUE_4" DOUBLE,
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150)
+);
+
+CREATE TABLE "METRICS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(255),
+ "DIRECTION" INTEGER NOT NULL DEFAULT 0,
+ "DOMAIN" VARCHAR(64),
+ "SHORT_NAME" VARCHAR(64),
+ "QUALITATIVE" BOOLEAN NOT NULL DEFAULT FALSE,
+ "VAL_TYPE" VARCHAR(8),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "ENABLED" BOOLEAN DEFAULT TRUE,
+ "ORIGIN" VARCHAR(3),
+ "WORST_VALUE" DOUBLE,
+ "BEST_VALUE" DOUBLE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN
+);
+
+CREATE TABLE "SNAPSHOTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "BUILD_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER NOT NULL,
+ "PARENT_SNAPSHOT_ID" INTEGER,
+ "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+ "PURGE_STATUS" INTEGER,
+ "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "ROOT_SNAPSHOT_ID" INTEGER,
+ "VERSION" VARCHAR(500),
+ "PATH" VARCHAR(500),
+ "DEPTH" INTEGER,
+ "ROOT_PROJECT_ID" INTEGER,
+ "PERIOD1_MODE" VARCHAR(100),
+ "PERIOD1_PARAM" VARCHAR(100),
+ "PERIOD1_DATE" TIMESTAMP,
+ "PERIOD2_MODE" VARCHAR(100),
+ "PERIOD2_PARAM" VARCHAR(100),
+ "PERIOD2_DATE" TIMESTAMP,
+ "PERIOD3_MODE" VARCHAR(100),
+ "PERIOD3_PARAM" VARCHAR(100),
+ "PERIOD3_DATE" TIMESTAMP,
+ "PERIOD4_MODE" VARCHAR(100),
+ "PERIOD4_PARAM" VARCHAR(100),
+ "PERIOD4_DATE" TIMESTAMP,
+ "PERIOD5_MODE" VARCHAR(100),
+ "PERIOD5_PARAM" VARCHAR(100),
+ "PERIOD5_DATE" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml
new file mode 100644
index 00000000000..0e6a35407d8
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute-result.xml
@@ -0,0 +1,35 @@
+<dataset>
+
+ <!-- Template rule -->
+ <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint"
+ description="Architectural constraint" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/>
+ <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/>
+ <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/>
+
+ <!-- Custom rule, 2 parameters should be added -->
+ <rules id="2" plugin_rule_key="ArchitecturalConstraint_2" plugin_name="xoo" name="Architectural constraint 2"
+ description="Architectural constraint 2" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-10-09"/>
+ <rules_parameters id="5" rule_id="2" name="max" param_type="INT" default_value="10" description="[null]"/>
+ <rules_parameters id="6" rule_id="2" name="format" param_type="STRING" default_value="csv" description="[null]"/>
+ <rules_parameters id="7" rule_id="2" name="type" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="8" rule_id="2" name="param" param_type="STRING" default_value="[null]" description="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml
new file mode 100644
index 00000000000..a951abd43de
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute.xml
@@ -0,0 +1,33 @@
+<dataset>
+
+ <!-- Template rule -->
+ <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint"
+ description="Architectural constraint" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/>
+ <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/>
+ <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/>
+
+ <!-- Custom rule, 2 parameters are existing, 2 parameters should be added -->
+ <rules id="2" plugin_rule_key="ArchitecturalConstraint_2" plugin_name="xoo" name="Architectural constraint 2"
+ description="Architectural constraint 2" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="5" rule_id="2" name="max" param_type="INT" default_value="10" description="[null]"/>
+ <rules_parameters id="6" rule_id="2" name="format" param_type="STRING" default_value="csv" description="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml
new file mode 100644
index 00000000000..ae74ca8fbe3
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter-result.xml
@@ -0,0 +1,35 @@
+<dataset>
+
+ <!-- Template rule -->
+ <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint"
+ description="Architectural constraint" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/>
+ <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/>
+ <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/>
+
+ <!-- Custom rule, 0 parameter are existing, 4 parameters should be added -->
+ <rules id="3" plugin_rule_key="ArchitecturalConstraint_3" plugin_name="xoo" name="Architectural constraint 3"
+ description="Architectural constraint 3" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-10-09"/>
+ <rules_parameters id="5" rule_id="3" name="max" param_type="INT" default_value="[null]" description="[null]"/>
+ <rules_parameters id="6" rule_id="3" name="format" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="7" rule_id="3" name="type" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="8" rule_id="3" name="param" param_type="STRING" default_value="[null]" description="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml
new file mode 100644
index 00000000000..ae7a8443d9a
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/execute_when_custom_rule_have_no_parameter.xml
@@ -0,0 +1,31 @@
+<dataset>
+
+ <!-- Template rule -->
+ <rules id="1" plugin_rule_key="ArchitecturalConstraint" plugin_name="xoo" name="Architectural constraint"
+ description="Architectural constraint" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="1" rule_id="1" name="max" param_type="INT" default_value="10" description="[null]"/>
+ <rules_parameters id="2" rule_id="1" name="format" param_type="STRING" default_value="txt" description="[null]"/>
+ <rules_parameters id="3" rule_id="1" name="type" param_type="STRING" default_value="[null]" description="[null]"/>
+ <rules_parameters id="4" rule_id="1" name="param" param_type="STRING" default_value="" description="[null]"/>
+
+ <!-- Custom rule, 0 parameter are existing, 4 parameters should be added -->
+ <rules id="3" plugin_rule_key="ArchitecturalConstraint_3" plugin_name="xoo" name="Architectural constraint 3"
+ description="Architectural constraint 3" status="READY" priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="1" created_at="2014-01-01" updated_at="2014-01-01"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml
new file mode 100644
index 00000000000..53ad673ec69
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/no_changes.xml
@@ -0,0 +1,29 @@
+<dataset>
+
+ <!-- Template rule -->
+ <rules id="10" plugin_rule_key="Rule2" plugin_name="xoo" name="Rule2" description="Rule2" status="READY" priority="1"
+ language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[true]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="10" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]"/>
+
+ <!-- Custom rule, no parameter should be added -->
+ <rules id="11" plugin_rule_key="Rule2_2" plugin_name="xoo" name="Rule2_2" description="Rule2_2" status="READY"
+ priority="1" language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" tags="[null]" system_tags="[null]" plugin_config_key="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="10" created_at="2014-01-01" updated_at="2014-01-01"/>
+ <rules_parameters id="11" rule_id="11" name="max" param_type="INT" default_value="10" description="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql
new file mode 100644
index 00000000000..0bf38617681
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/AddMissingCustomRuleParametersMigrationTest/schema.sql
@@ -0,0 +1,40 @@
+CREATE TABLE "RULES_PARAMETERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "RULE_ID" INTEGER NOT NULL,
+ "NAME" VARCHAR(128) NOT NULL,
+ "PARAM_TYPE" VARCHAR(512) NOT NULL,
+ "DEFAULT_VALUE" VARCHAR(4000),
+ "DESCRIPTION" VARCHAR(4000)
+);
+
+CREATE TABLE "RULES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PLUGIN_RULE_KEY" VARCHAR(200) NOT NULL,
+ "PLUGIN_NAME" VARCHAR(255) NOT NULL,
+ "DESCRIPTION" VARCHAR(16777215),
+ "DESCRIPTION_FORMAT" VARCHAR(20),
+ "PRIORITY" INTEGER,
+ "IS_TEMPLATE" BOOLEAN DEFAULT FALSE,
+ "TEMPLATE_ID" INTEGER,
+ "PLUGIN_CONFIG_KEY" VARCHAR(500),
+ "NAME" VARCHAR(200),
+ "STATUS" VARCHAR(40),
+ "LANGUAGE" VARCHAR(20),
+ "NOTE_DATA" CLOB(2147483647),
+ "NOTE_USER_LOGIN" VARCHAR(255),
+ "NOTE_CREATED_AT" TIMESTAMP,
+ "NOTE_UPDATED_AT" TIMESTAMP,
+ "CHARACTERISTIC_ID" INTEGER,
+ "DEFAULT_CHARACTERISTIC_ID" INTEGER,
+ "REMEDIATION_FUNCTION" VARCHAR(20),
+ "DEFAULT_REMEDIATION_FUNCTION" VARCHAR(20),
+ "REMEDIATION_COEFF" VARCHAR(20),
+ "DEFAULT_REMEDIATION_COEFF" VARCHAR(20),
+ "REMEDIATION_OFFSET" VARCHAR(20),
+ "DEFAULT_REMEDIATION_OFFSET" VARCHAR(20),
+ "EFFORT_TO_FIX_DESCRIPTION" VARCHAR(4000),
+ "TAGS" VARCHAR(4000),
+ "SYSTEM_TAGS" VARCHAR(4000),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml
new file mode 100644
index 00000000000..49462b9bbcd
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute-result.xml
@@ -0,0 +1,12 @@
+<dataset>
+
+ <!-- ok -->
+ <activities id="1" log_key="abcde" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE"
+ log_action="ACTIVATED" log_message="[null]"
+ data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;profileKey=java-findbugs-74105;severity=MAJOR"/>
+
+ <!-- ko - deleted -->
+ <!--<activities id="2" log_key="fghij" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE"
+ log_action="ACTIVATED" log_message="[null]"
+ data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;param_xpath=foo;bar;baz"/>-->
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml
new file mode 100644
index 00000000000..415484745fb
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/execute.xml
@@ -0,0 +1,12 @@
+<dataset>
+
+ <!-- ok -->
+ <activities id="1" log_key="abcde" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE"
+ log_action="ACTIVATED" log_message="[null]"
+ data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;profileKey=java-findbugs-74105;severity=MAJOR"/>
+
+ <!-- ko -->
+ <activities id="2" log_key="fghij" created_at="2014-01-10" user_login="[null]" log_type="QPROFILE"
+ log_action="ACTIVATED" log_message="[null]"
+ data_field="ruleKey=findbugs:PT_RELATIVE_PATH_TRAVERSAL;param_xpath=foo;bar;baz"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql
new file mode 100644
index 00000000000..336e2fd7f01
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v451/DeleteUnescapedActivitiesTest/schema.sql
@@ -0,0 +1,10 @@
+CREATE TABLE "ACTIVITIES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "LOG_KEY" VARCHAR(250),
+ "CREATED_AT" TIMESTAMP,
+ "USER_LOGIN" VARCHAR(30),
+ "LOG_TYPE" VARCHAR(250),
+ "LOG_ACTION" VARCHAR(250),
+ "LOG_MESSAGE" VARCHAR(250),
+ "DATA_FIELD" CLOB(2147483647)
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml
new file mode 100644
index 00000000000..6810f0a5dfe
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-invalid-duplication.xml
@@ -0,0 +1,15 @@
+<dataset>
+
+ <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=""
+ line_hashes=""
+ data_hash=""/>
+
+ <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=",,,,,,,,,,,,,,,class Foo {&#13;&#10;,,,,,,,,,,,,,,, // Empty&#13;&#10;,,,,,,,,,,,,,,,}&#13;&#10;,,,,,,,,,,,,,,,&#13;&#10;"
+ line_hashes="6a19ce786467960a3a9b0d26383a464a&#10;aab2dbc5fdeaa80b050b1d049ede357c&#10;cbb184dd8e05c9709e5dcaedaa0495cf&#10;&#10;"
+ data_hash=""/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml
new file mode 100644
index 00000000000..fa4d6332c5b
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after-with-scm.xml
@@ -0,0 +1,15 @@
+<dataset>
+
+ <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=""
+ line_hashes=""
+ data_hash=""/>
+
+ <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data="aef12a,alice,2014-04-25T12:34:56+0100,1,4,2,2,5,3,3,6,4,,,1,class Foo {&#13;&#10;abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,2, // Empty&#13;&#10;afb789,carol,2014-03-23T12:34:56+0100,0,,,0,,,0,,,,,,}&#13;&#10;afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,,&#13;&#10;"
+ line_hashes="6a19ce786467960a3a9b0d26383a464a&#10;aab2dbc5fdeaa80b050b1d049ede357c&#10;cbb184dd8e05c9709e5dcaedaa0495cf&#10;&#10;"
+ data_hash=""/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml
new file mode 100644
index 00000000000..6810f0a5dfe
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/after.xml
@@ -0,0 +1,15 @@
+<dataset>
+
+ <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=""
+ line_hashes=""
+ data_hash=""/>
+
+ <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=",,,,,,,,,,,,,,,class Foo {&#13;&#10;,,,,,,,,,,,,,,, // Empty&#13;&#10;,,,,,,,,,,,,,,,}&#13;&#10;,,,,,,,,,,,,,,,&#13;&#10;"
+ line_hashes="6a19ce786467960a3a9b0d26383a464a&#10;aab2dbc5fdeaa80b050b1d049ede357c&#10;cbb184dd8e05c9709e5dcaedaa0495cf&#10;&#10;"
+ data_hash=""/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml
new file mode 100644
index 00000000000..065480f088d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/before.xml
@@ -0,0 +1,134 @@
+<dataset>
+
+ <metrics id="1" name="revisions_by_line" description="[null]" direction="0" domain="SCM"
+ short_name="Revisions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="2" name="authors_by_line" description="[null]" direction="0" domain="SCM" short_name="Authors by line"
+ qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="3" name="last_commit_datetimes_by_line" description="[null]" direction="0" domain="SCM"
+ short_name="Last commit dates by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="4" name="coverage_line_hits_data" description="[null]" direction="0" domain="Test"
+ short_name="Coverage hits by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="5" name="conditions_by_line" description="[null]" direction="0" domain="Tests"
+ short_name="Conditions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="6" name="covered_conditions_by_line" description="[null]" direction="0" domain="Tests"
+ short_name="Covered conditions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="7" name="it_coverage_line_hits_data" description="[null]" direction="0" domain="Test"
+ short_name="Coverage hits by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="8" name="it_conditions_by_line" description="[null]" direction="0" domain="Tests"
+ short_name="Conditions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="9" name="it_covered_conditions_by_line" description="[null]" direction="0" domain="Tests"
+ short_name="Covered conditions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="10" name="overall_coverage_line_hits_data" description="[null]" direction="0" domain="Test"
+ short_name="Coverage hits by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="11" name="overall_conditions_by_line" description="[null]" direction="0" domain="Tests"
+ short_name="Conditions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="12" name="overall_covered_conditions_by_line" description="[null]" direction="0" domain="Tests"
+ short_name="Covered conditions by line" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+ <metrics id="13" name="duplications_data" description="[null]" direction="0" domain="Duplications"
+ short_name="Duplication data" qualitative="false" val_type="DATA"
+ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]"
+ optimized_best_value="[null]" hidden="[false]" delete_historical_data="false"/>
+
+ <projects id="1" uuid="uuid-MyProject" kee="MyProject" scope="PRJ" qualifier="TRK"/>
+ <projects id="2" uuid="uuid-prj" kee="MyProject:src/main/xoo/prj" scope="DIR" qualifier="DIR"/>
+ <projects id="3" uuid="uuid-MyFile.xoo" kee="MyProject:src/main/xoo/prj/MyFile.xoo" scope="FIL" qualifier="FIL"/>
+ <projects id="4" uuid="uuid-Migrated.xoo" kee="MyProject:src/main/xoo/prj/Migrated.xoo" scope="FIL" qualifier="FIL"/>
+
+ <snapshots id="1" project_id="1" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ depth="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02" build_date="2011-09-29"
+ version="2.1-SNAPSHOT" path="1.2."/>
+ <snapshots id="2" project_id="1" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ depth="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02" build_date="2011-09-29"
+ version="2.1-SNAPSHOT" path="1.2."/>
+
+ <snapshots id="3" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ depth="1" scope="DIR" qualifier="DIR" created_at="2008-12-02" build_date="2011-09-29"
+ version="2.1-SNAPSHOT" path="1.2."/>
+ <snapshots id="4" project_id="2" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="2"
+ status="P" islast="[true]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ depth="1" scope="DIR" qualifier="DIR" created_at="2008-12-02" build_date="2011-09-29"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ version="2.1-SNAPSHOT" path="1.2."/>
+
+ <snapshots id="5" project_id="3" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ depth="1" scope="DIR" qualifier="DIR" created_at="2008-12-02" build_date="2011-09-29"
+ version="2.1-SNAPSHOT" path="1.2."/>
+ <snapshots id="6" project_id="3" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="2"
+ status="P" islast="[true]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ depth="1" scope="FIL" qualifier="FIL" created_at="2008-12-02" build_date="2011-09-29"
+ version="2.1-SNAPSHOT" path="1.2."/>
+
+ <snapshots id="7" project_id="4" parent_snapshot_id="5" root_project_id="1" root_snapshot_id="2"
+ status="P" islast="[true]" purge_status="1"
+ period1_mode="days1" period1_param="30" period1_date="2011-09-24"
+ period2_mode="days2" period2_param="31" period2_date="2011-09-25"
+ period3_mode="days3" period3_param="32" period3_date="2011-09-26"
+ period4_mode="days4" period4_param="33" period4_date="2011-09-27"
+ period5_mode="days5" period5_param="34" period5_date="2011-09-28"
+ depth="1" scope="FIL" qualifier="FIL" created_at="2008-12-02" build_date="2011-09-29"
+ version="2.1-SNAPSHOT" path="1.2."/>
+
+ <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=""
+ line_hashes=""
+ data_hash=""/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql
new file mode 100644
index 00000000000..481ea89ba0a
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql
@@ -0,0 +1,119 @@
+
+CREATE TABLE "METRICS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(255),
+ "DIRECTION" INTEGER NOT NULL DEFAULT 0,
+ "DOMAIN" VARCHAR(64),
+ "SHORT_NAME" VARCHAR(64),
+ "QUALITATIVE" BOOLEAN NOT NULL DEFAULT FALSE,
+ "VAL_TYPE" VARCHAR(8),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "ENABLED" BOOLEAN DEFAULT TRUE,
+ "ORIGIN" VARCHAR(3),
+ "WORST_VALUE" DOUBLE,
+ "BEST_VALUE" DOUBLE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN
+);
+
+CREATE TABLE "SNAPSHOTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "BUILD_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER NOT NULL,
+ "PARENT_SNAPSHOT_ID" INTEGER,
+ "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+ "PURGE_STATUS" INTEGER,
+ "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "ROOT_SNAPSHOT_ID" INTEGER,
+ "VERSION" VARCHAR(500),
+ "PATH" VARCHAR(500),
+ "DEPTH" INTEGER,
+ "ROOT_PROJECT_ID" INTEGER,
+ "PERIOD1_MODE" VARCHAR(100),
+ "PERIOD1_PARAM" VARCHAR(100),
+ "PERIOD1_DATE" TIMESTAMP,
+ "PERIOD2_MODE" VARCHAR(100),
+ "PERIOD2_PARAM" VARCHAR(100),
+ "PERIOD2_DATE" TIMESTAMP,
+ "PERIOD3_MODE" VARCHAR(100),
+ "PERIOD3_PARAM" VARCHAR(100),
+ "PERIOD3_DATE" TIMESTAMP,
+ "PERIOD4_MODE" VARCHAR(100),
+ "PERIOD4_PARAM" VARCHAR(100),
+ "PERIOD4_DATE" TIMESTAMP,
+ "PERIOD5_MODE" VARCHAR(100),
+ "PERIOD5_PARAM" VARCHAR(100),
+ "PERIOD5_DATE" TIMESTAMP
+);
+
+CREATE TABLE "SNAPSHOT_SOURCES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "SNAPSHOT_ID" INTEGER NOT NULL,
+ "UPDATED_AT" TIMESTAMP,
+ "DATA" CLOB(2147483647)
+);
+
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
+
+CREATE TABLE "PROJECT_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "VALUE" DOUBLE,
+ "METRIC_ID" INTEGER NOT NULL,
+ "SNAPSHOT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "RULES_CATEGORY_ID" INTEGER,
+ "TEXT_VALUE" VARCHAR(4000),
+ "TENDENCY" INTEGER,
+ "MEASURE_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER,
+ "ALERT_STATUS" VARCHAR(5),
+ "ALERT_TEXT" VARCHAR(4000),
+ "URL" VARCHAR(2000),
+ "DESCRIPTION" VARCHAR(4000),
+ "RULE_PRIORITY" INTEGER,
+ "CHARACTERISTIC_ID" INTEGER,
+ "PERSON_ID" INTEGER,
+ "VARIATION_VALUE_1" DOUBLE,
+ "VARIATION_VALUE_2" DOUBLE,
+ "VARIATION_VALUE_3" DOUBLE,
+ "VARIATION_VALUE_4" DOUBLE,
+ "VARIATION_VALUE_5" DOUBLE,
+ "MEASURE_DATA" BINARY(167772150)
+);
+
+CREATE TABLE "FILE_SOURCES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "FILE_UUID" VARCHAR(50) NOT NULL,
+ "DATA" CLOB(2147483647),
+ "LINE_HASHES" CLOB(2147483647),
+ "DATA_HASH" VARCHAR(50) NOT NULL,
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml
new file mode 100644
index 00000000000..7f2e3baa257
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/before.xml
@@ -0,0 +1,75 @@
+<dataset>
+
+ <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="200"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="2014-05-12"
+ updated_at="2014-05-13"
+ CREATED_AT_MS="[null]"
+ UPDATED_AT_MS="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="200"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+
+ created_at="2014-05-12"
+ updated_at="2014-05-13"
+ CREATED_AT_MS="1500000000000"
+ UPDATED_AT_MS="1500000000000"
+ />
+
+ <!-- NULL dates -->
+ <issues id="3" kee="MISSINGDATES" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="200"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ issue_creation_date="[null]"
+ issue_update_date="[null]"
+ issue_close_date="[null]"
+ created_at="[null]"
+ updated_at="[null]"
+ CREATED_AT_MS="[null]"
+ UPDATED_AT_MS="[null]"
+ />
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql
new file mode 100644
index 00000000000..66c7d3a7a9f
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedIssueLongDatesTest/schema.sql
@@ -0,0 +1,28 @@
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(50) UNIQUE NOT NULL,
+ "COMPONENT_ID" INTEGER NOT NULL,
+ "ROOT_COMPONENT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "SEVERITY" VARCHAR(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" VARCHAR(4000),
+ "LINE" INTEGER,
+ "EFFORT_TO_FIX" DOUBLE,
+ "TECHNICAL_DEBT" INTEGER,
+ "STATUS" VARCHAR(20),
+ "RESOLUTION" VARCHAR(20),
+ "CHECKSUM" VARCHAR(1000),
+ "REPORTER" VARCHAR(255),
+ "ASSIGNEE" VARCHAR(255),
+ "AUTHOR_LOGIN" VARCHAR(255),
+ "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+ "ISSUE_ATTRIBUTES" VARCHAR(4000),
+ "ISSUE_CREATION_DATE" TIMESTAMP,
+ "ISSUE_CLOSE_DATE" TIMESTAMP,
+ "ISSUE_UPDATE_DATE" TIMESTAMP,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "UPDATED_AT_MS" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml
new file mode 100644
index 00000000000..0b0dfa1d728
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/after.xml
@@ -0,0 +1,28 @@
+<dataset>
+
+ <projects id="1" kee="project" name="project" long_name="project" scope="PRJ" qualifier="TRK" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="123456789"/>
+
+ <projects id="2" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="123456789"/>
+
+ <!-- File should not be updated -->
+ <projects id="3" kee="file" name="File" long_name="File" scope="FIL" qualifier="CLA" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+
+ <projects id="4" kee="disabled" name="Disabled" long_name="Disabled" scope="PRJ" qualifier="TRK" root_id="1"
+ description="[null]"
+ enabled="false" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml
new file mode 100644
index 00000000000..8cf83a39b03
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/before.xml
@@ -0,0 +1,28 @@
+<dataset>
+
+ <projects id="1" kee="project" name="project" long_name="project" scope="PRJ" qualifier="TRK" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+
+ <projects id="2" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+
+ <!-- File should not be updated -->
+ <projects id="3" kee="file" name="File" long_name="File" scope="FIL" qualifier="CLA" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+
+ <projects id="4" kee="disabled" name="Disabled" long_name="Disabled" scope="PRJ" qualifier="TRK" root_id="1"
+ description="[null]"
+ enabled="false" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01" authorization_updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql
new file mode 100644
index 00000000000..e10b82bd90e
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/InsertProjectsAuthorizationUpdatedAtMigrationTest/schema.sql
@@ -0,0 +1,18 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "KEE" VARCHAR(400),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "ROOT_ID" INTEGER,
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml
new file mode 100644
index 00000000000..3ea725be763
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml
@@ -0,0 +1,93 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- sub module -->
+ <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+ <!-- directory -->
+ <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="src/org/struts" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"
+ created_at="2014-06-18"/>
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3."/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="RequestContext.java" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java" created_at="2014-06-18"/>
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml
new file mode 100644
index 00000000000..e5f8a0223ed
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml
@@ -0,0 +1,58 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module with a snapshot having no islast=true -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- file linked on a no more existing project -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="RequestContext.java" root_id="999"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java" created_at="2014-06-18"/>
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="999" root_project_id="999" root_snapshot_id="999"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml
new file mode 100644
index 00000000000..68496498454
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_developer.xml
@@ -0,0 +1,40 @@
+<dataset>
+
+ <!-- developer -->
+ <projects id="1" kee="DEV:developer@company.net" name="developer@company.net" long_name="Developer" scope="PRJ"
+ qualifier="DEV" root_id="[null]" description="[null]"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path=""
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="DEV" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- technical project -->
+ <projects id="2" root_id="1" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:developer@company.net:org.struts:struts"
+ name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="10" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="1" scope="PRJ" qualifier="DEV_PRJ" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml
new file mode 100644
index 00000000000..47998eecac3
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_disable_components.xml
@@ -0,0 +1,93 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- removed module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!--removed sub module -->
+ <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]"
+ description="[null]" enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+ <!-- removed directory -->
+ <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="src/org/struts" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"
+ created_at="2014-06-18"/>
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3."/>
+
+ <!-- removed file -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="RequestContext.java" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[false]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java" created_at="2014-06-18"/>
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml
new file mode 100644
index 00000000000..89709dca85d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_library.xml
@@ -0,0 +1,12 @@
+<dataset>
+
+ <!-- library -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library"
+ name="org.hamcrest:hamcrest-library"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="[null]" long_name="org.hamcrest:hamcrest-library"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml
new file mode 100644
index 00000000000..c485cc06664
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_provisioned_project.xml
@@ -0,0 +1,11 @@
+<dataset>
+
+ <!-- provisioned project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml
new file mode 100644
index 00000000000..b3ae4868b4c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_view.xml
@@ -0,0 +1,57 @@
+<dataset>
+
+ <!-- view -->
+ <projects id="1" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]"
+ description="[null]"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="VW" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- sub view -->
+ <projects id="2" kee="subView" name="Sub View" long_name="Sub View" scope="PRJ" qualifier="SVW" root_id="1"
+ description="[null]"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-09-01"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="SVW" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- technical project -->
+ <projects id="3" root_id="1" scope="FIL" qualifier="TRK" kee="vieworg.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="10" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="1" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml
new file mode 100644
index 00000000000..c0b7676303d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_module_has_no_root_id.xml
@@ -0,0 +1,38 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module with null root id (probably a project that became a module) -->
+ <projects id="2" root_id="[null]" kee="org.struts:struts-core" name="Struts Core"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml
new file mode 100644
index 00000000000..e42d8158831
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_fail_when_project_has_two_active_snapshots.xml
@@ -0,0 +1,48 @@
+<dataset>
+
+ <!-- root project with 2 snapshots having islast to true-->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+ <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module linked on second active snapshot of the project -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="10" root_project_id="1" root_snapshot_id="10"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="10."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml
new file mode 100644
index 00000000000..76b63671f12
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/not_migrate_already_migrated_components.xml
@@ -0,0 +1,113 @@
+<dataset>
+
+ <!-- root project migrated -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module migrated -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="BCDE" project_uuid="ABCD" module_uuid="ABCD" module_uuid_path="ABCD"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- sub module not migrated -->
+ <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2014-06-18"/>
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+ <!-- directory not migrated -->
+ <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="src/org/struts" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"
+ created_at="2014-06-18"/>
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3."/>
+
+ <!-- file not migrated -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ name="RequestContext.java" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java" created_at="2014-06-18"/>
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+ <!-- removed file linked on module, migrated -->
+ <projects long_name="org.struts.RequestContext2" id="6" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext2.java"
+ uuid="DCBA" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path="ABCD.BCDE"
+ name="RequestContext.java" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[false]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java" created_at="2014-06-18"/>
+
+ <snapshots id="6" project_id="6" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00"
+ build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql
new file mode 100644
index 00000000000..c8fee3449dd
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/PopulateProjectsUuidColumnsMigrationTest/schema.sql
@@ -0,0 +1,54 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "SNAPSHOTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "BUILD_DATE" TIMESTAMP,
+ "PROJECT_ID" INTEGER NOT NULL,
+ "PARENT_SNAPSHOT_ID" INTEGER,
+ "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+ "PURGE_STATUS" INTEGER,
+ "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "ROOT_SNAPSHOT_ID" INTEGER,
+ "VERSION" VARCHAR(500),
+ "PATH" VARCHAR(500),
+ "DEPTH" INTEGER,
+ "ROOT_PROJECT_ID" INTEGER,
+ "PERIOD1_MODE" VARCHAR(100),
+ "PERIOD1_PARAM" VARCHAR(100),
+ "PERIOD1_DATE" TIMESTAMP,
+ "PERIOD2_MODE" VARCHAR(100),
+ "PERIOD2_PARAM" VARCHAR(100),
+ "PERIOD2_DATE" TIMESTAMP,
+ "PERIOD3_MODE" VARCHAR(100),
+ "PERIOD3_PARAM" VARCHAR(100),
+ "PERIOD3_DATE" TIMESTAMP,
+ "PERIOD4_MODE" VARCHAR(100),
+ "PERIOD4_PARAM" VARCHAR(100),
+ "PERIOD4_DATE" TIMESTAMP,
+ "PERIOD5_MODE" VARCHAR(100),
+ "PERIOD5_PARAM" VARCHAR(100),
+ "PERIOD5_DATE" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml
new file mode 100644
index 00000000000..2be1be35633
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute-result.xml
@@ -0,0 +1,33 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="No sort field"
+ user_login="stephane"
+ shared="[true]"
+ description="no not touch"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="2"
+ name="Has sort field"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|projectUuids=ABC"
+ created_at="2013-06-10"
+ updated_at="2014-10-29 00:00:00.0"/>
+
+ <issue_filters
+ id="3"
+ name="corner-case"
+ user_login="michael"
+ shared="[true]"
+ description="do not touch"
+ data="statuses=CLOSED|resort=true"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml
new file mode 100644
index 00000000000..e3fdb367e19
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/execute.xml
@@ -0,0 +1,33 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="No sort field"
+ user_login="stephane"
+ shared="[true]"
+ description="no not touch"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="2"
+ name="Has sort field"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|asc=true|projectUuids=ABC"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="3"
+ name="corner-case"
+ user_login="michael"
+ shared="[true]"
+ description="do not touch"
+ data="statuses=CLOSED|resort=true"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql
new file mode 100644
index 00000000000..0627153a62d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/RemoveSortFieldFromIssueFiltersMigrationTest/schema.sql
@@ -0,0 +1,10 @@
+CREATE TABLE "ISSUE_FILTERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(100) NOT NULL,
+ "SHARED" BOOLEAN NOT NULL DEFAULT FALSE,
+ "USER_LOGIN" VARCHAR(255),
+ "DESCRIPTION" VARCHAR(4000),
+ "DATA" CLOB(2147483647),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml
new file mode 100644
index 00000000000..7f657ff712c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated-result.xml
@@ -0,0 +1,43 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="Struts Issues"
+ user_login="stephane"
+ shared="[true]"
+ description="All issues of Struts"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_login="michael"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="3"
+ name="Sonar Open issues"
+ user_login="michael"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=CLOSED|projectUuids=ABCD|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="4"
+ name="Bad component roots fields"
+ user_login="michael"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=CLOSED|projectUuids=|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml
new file mode 100644
index 00000000000..524a2bef4a7
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/do_not_execute_if_already_migrated.xml
@@ -0,0 +1,50 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="."
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+
+ <issue_filters
+ id="1"
+ name="Struts Issues"
+ user_login="stephane"
+ shared="[true]"
+ description="All issues of Struts"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_login="michael"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="3"
+ name="Sonar Open issues"
+ user_login="michael"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=CLOSED|projectUuids=ABCD|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="4"
+ name="Bad component roots fields"
+ user_login="michael"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=CLOSED|projectUuids=|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml
new file mode 100644
index 00000000000..3d2bb6937e5
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute-result.xml
@@ -0,0 +1,63 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="Struts Issues"
+ user_login="stephane"
+ shared="[true]"
+ description="All issues of Struts"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2014-10-29"/>
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_login="michael"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="3"
+ name="Sonar Open issues"
+ user_login="michael"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=CLOSED|projectUuids=ABCD|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2014-10-29"/>
+
+ <issue_filters
+ id="4"
+ name="Bad component roots fields"
+ user_login="michael"
+ shared="[true]"
+ description="Bad component roots fields"
+ data="statuses=CLOSED||resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2014-10-29"/>
+
+ <issue_filters
+ id="5"
+ name="Linked on not existing file"
+ user_login="michael"
+ shared="[true]"
+ description="Linked on not existing file"
+ data="statuses=CLOSED||resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2014-10-29"/>
+
+ <issue_filters
+ id="6"
+ name="Empty data"
+ user_login="michael"
+ shared="[true]"
+ description="Empty data"
+ data="[null]"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml
new file mode 100644
index 00000000000..a952ef40542
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/execute.xml
@@ -0,0 +1,70 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="."
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+
+ <issue_filters
+ id="1"
+ name="Struts Issues"
+ user_login="stephane"
+ shared="[true]"
+ description="All issues of Struts"
+ data="componentRoots=org.struts:struts"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_login="michael"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="3"
+ name="Sonar Open issues"
+ user_login="michael"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=CLOSED|componentRoots=org.struts:struts|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="4"
+ name="Bad component roots fields"
+ user_login="michael"
+ shared="[true]"
+ description="Bad component roots fields"
+ data="statuses=CLOSED|componentRoots=|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="5"
+ name="Linked on not existing file"
+ user_login="michael"
+ shared="[true]"
+ description="Linked on not existing file"
+ data="statuses=CLOSED|componentRoots=unknown|resolution=FIXED"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <issue_filters
+ id="6"
+ name="Empty data"
+ user_login="michael"
+ shared="[true]"
+ description="Empty data"
+ data="[null]"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql
new file mode 100644
index 00000000000..a1182dd7d46
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/ReplaceIssueFiltersProjectKeyByUuidTest/schema.sql
@@ -0,0 +1,32 @@
+CREATE TABLE "ISSUE_FILTERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(100) NOT NULL,
+ "SHARED" BOOLEAN NOT NULL DEFAULT FALSE,
+ "USER_LOGIN" VARCHAR(255),
+ "DESCRIPTION" VARCHAR(4000),
+ "DATA" CLOB(2147483647),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql
new file mode 100644
index 00000000000..3e799c31508
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddIssuesColumnsTest/schema.sql
@@ -0,0 +1,26 @@
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(50) UNIQUE NOT NULL,
+ "COMPONENT_ID" INTEGER NOT NULL,
+ "ROOT_COMPONENT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "SEVERITY" VARCHAR(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" VARCHAR(4000),
+ "LINE" INTEGER,
+ "EFFORT_TO_FIX" DOUBLE,
+ "TECHNICAL_DEBT" INTEGER,
+ "STATUS" VARCHAR(20),
+ "RESOLUTION" VARCHAR(20),
+ "CHECKSUM" VARCHAR(1000),
+ "REPORTER" VARCHAR(255),
+ "ASSIGNEE" VARCHAR(255),
+ "AUTHOR_LOGIN" VARCHAR(255),
+ "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+ "ISSUE_ATTRIBUTES" VARCHAR(4000),
+ "ISSUE_CREATION_DATE" TIMESTAMP,
+ "ISSUE_CLOSE_DATE" TIMESTAMP,
+ "ISSUE_UPDATE_DATE" TIMESTAMP,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml
new file mode 100644
index 00000000000..5df0387b5f8
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/do_nothing_when_already_migrated.xml
@@ -0,0 +1,73 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+ <characteristics id="2" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="3" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+ <characteristics id="4" kee="PORTABILITY_COMPLIANCE" name="Portability Compliance" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="5" kee="MAINTAINABILITY" name="Maintainability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="3" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+ <characteristics id="6" kee="MAINTAINABILITY_COMPLIANCE" name="Maintainability Compliance" parent_id="5"
+ rule_id="[null]" characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="7" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+ <characteristics id="8" kee="SECURITY_COMPLIANCE" name="Security Compliance" parent_id="7" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+
+ <characteristics id="9" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="5"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+ <characteristics id="10" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="9" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+ <characteristics id="11" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="9" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+ <characteristics id="12" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="9" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="13" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]"
+ characteristic_order="6" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-20"/>
+ <characteristics id="14" kee="EFFICIENCY_COMPLIANCE" name="Efficiency Compliance" parent_id="13" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="15" kee="CHANGEABILITY" name="Changeability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="7" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-20"/>
+ <characteristics id="16" kee="CHANGEABILITY_COMPLIANCE" name="Changeability Compliance" parent_id="15"
+ rule_id="[null]" characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="17" kee="RELIABILITY" name="Reliability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="8" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-20"/>
+ <characteristics id="18" kee="RELIABILITY_COMPLIANCE" name="Reliability Compliance" parent_id="17" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="19" kee="TESTABILITY" name="Testability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="9" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-20"/>
+ <characteristics id="20" kee="TESTABILITY_COMPLIANCE" name="Testability Compliance" parent_id="19" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml
new file mode 100644
index 00000000000..871dedcb5e9
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/empty.xml
@@ -0,0 +1,3 @@
+<dataset>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml
new file mode 100644
index 00000000000..72521ba290d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_as_characteristic.xml
@@ -0,0 +1,11 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="REUSABILITY_COMPLIANCE" name="Compliance" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml
new file mode 100644
index 00000000000..62a08ca6f7c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_compliance_already_exists_under_wrong_characteristic.xml
@@ -0,0 +1,16 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="3" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="2" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20"
+ updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml
new file mode 100644
index 00000000000..9db2b164d0d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/fail_if_usability_exists_as_sub_characteristic.xml
@@ -0,0 +1,11 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="USABILITY" name="Usability" parent_id="1" rule_id="[null]" characteristic_order="[null]"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml
new file mode 100644
index 00000000000..62b66901fe8
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists-result.xml
@@ -0,0 +1,38 @@
+<dataset>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="3" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- New characteristic 'Usability' is on the top (order 1) -->
+ <characteristics id="3" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="1"
+ enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="4" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="5" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="6" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+
+ <!-- New sub characteristic 'Compliance' under Reusability -->
+ <characteristics id="7" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Portability -->
+ <characteristics id="8" kee="PORTABILITY_COMPLIANCE" name="Portability Compliance" parent_id="2" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml
new file mode 100644
index 00000000000..a8394be84fa
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/insert_usability_at_the_top_if_security_does_exists.xml
@@ -0,0 +1,11 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml
new file mode 100644
index 00000000000..b677f0f351a
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate-result.xml
@@ -0,0 +1,94 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="3" kee="MAINTAINABILITY" name="Maintainability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="3" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="4" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="5" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]"
+ characteristic_order="6" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="6" kee="CHANGEABILITY" name="Changeability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="7" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="7" kee="RELIABILITY" name="Reliability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="8" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="8" kee="TESTABILITY" name="Testability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="9" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- New characteristic 'Usability' is after Security -->
+ <characteristics id="9" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="5"
+ enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <!-- New sub characteristics under Usability -->
+ <characteristics id="10" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="9" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="11" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="9" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="12" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="9" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Reusability -->
+ <characteristics id="13" kee="REUSABILITY_COMPLIANCE" name="Reusability Compliance" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Portability -->
+ <characteristics id="14" kee="PORTABILITY_COMPLIANCE" name="Portability Compliance" parent_id="2" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Maintainability -->
+ <characteristics id="15" kee="MAINTAINABILITY_COMPLIANCE" name="Maintainability Compliance" parent_id="3"
+ rule_id="[null]" characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Security -->
+ <characteristics id="16" kee="SECURITY_COMPLIANCE" name="Security Compliance" parent_id="4" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Efficiency -->
+ <characteristics id="17" kee="EFFICIENCY_COMPLIANCE" name="Efficiency Compliance" parent_id="5" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Changeability -->
+ <characteristics id="18" kee="CHANGEABILITY_COMPLIANCE" name="Changeability Compliance" parent_id="6" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Reliability -->
+ <characteristics id="19" kee="RELIABILITY_COMPLIANCE" name="Reliability Compliance" parent_id="7" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Testability -->
+ <characteristics id="20" kee="TESTABILITY_COMPLIANCE" name="Testability Compliance" parent_id="8" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml
new file mode 100644
index 00000000000..52505623c3d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/migrate.xml
@@ -0,0 +1,35 @@
+<dataset>
+
+ <characteristics id="1" kee="REUSABILITY" name="Reusability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="1" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="PORTABILITY" name="Portability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="2" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="3" kee="MAINTAINABILITY" name="Maintainability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="3" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="4" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="5" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]"
+ characteristic_order="5" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="6" kee="CHANGEABILITY" name="Changeability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="6" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="7" kee="RELIABILITY" name="Reliability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="7" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="8" kee="TESTABILITY" name="Testability" parent_id="[null]" rule_id="[null]"
+ characteristic_order="8" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml
new file mode 100644
index 00000000000..81050d0ee0c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/not_fail_if_some_deprecated_requirements_still_exists_in_db.xml
@@ -0,0 +1,19 @@
+<dataset>
+
+ <characteristics id="1" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="1"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+ <characteristics id="2" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+ <characteristics id="3" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2013-11-20"
+ updated_at="[null]"/>
+ <characteristics id="4" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2013-11-20" updated_at="[null]"/>
+
+ <characteristics id="5" kee="[null]" name="[null]" parent_id="3" rule_id="3" characteristic_order="[null]"
+ enabled="[true]" created_at="2013-11-20" updated_at="2013-11-22"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql
new file mode 100644
index 00000000000..98c025def6b
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/schema.sql
@@ -0,0 +1,11 @@
+CREATE TABLE "CHARACTERISTICS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(100),
+ "NAME" VARCHAR(100),
+ "PARENT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "CHARACTERISTIC_ORDER" INTEGER,
+ "ENABLED" BOOLEAN,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml
new file mode 100644
index 00000000000..86851f3d471
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists-result.xml
@@ -0,0 +1,38 @@
+<dataset>
+
+ <characteristics id="1" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <!-- Oder has changed : this characteristic is now one step lower -->
+ <characteristics id="2" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]"
+ characteristic_order="6" enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- Usability is moved after Security -->
+ <characteristics id="3" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="5"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2015-02-15"/>
+
+ <!-- New sub characteristics under Usability -->
+ <characteristics id="4" kee="USABILITY_ACCESSIBILITY" name="Accessibility" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="5" kee="USABILITY_EASE_OF_USE" name="Ease of Use" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+ <characteristics id="6" kee="USABILITY_COMPLIANCE" name="Usability Compliance" parent_id="3" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Security -->
+ <characteristics id="7" kee="SECURITY_COMPLIANCE" name="Security Compliance" parent_id="1" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]" created_at="2015-02-15"
+ updated_at="[null]"/>
+
+ <!-- New sub characteristic 'Compliance' under Efficiency -->
+ <characteristics id="8" kee="EFFICIENCY_COMPLIANCE" name="Efficiency Compliance" parent_id="2" rule_id="[null]"
+ characteristic_order="[null]" enabled="[true]"
+ created_at="2015-02-15" updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml
new file mode 100644
index 00000000000..2e75b7324e7
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/AddNewCharacteristicsTest/update_usability_if_already_exists.xml
@@ -0,0 +1,16 @@
+<dataset>
+
+ <characteristics id="1" kee="SECURITY" name="Security" parent_id="[null]" rule_id="[null]" characteristic_order="4"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <characteristics id="2" kee="EFFICIENCY" name="Efficiency" parent_id="[null]" rule_id="[null]"
+ characteristic_order="5" enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+ <!-- Usability should be move after Security -->
+ <characteristics id="3" kee="USABILITY" name="Usability" parent_id="[null]" rule_id="[null]" characteristic_order="6"
+ enabled="[true]" created_at="2013-11-20"
+ updated_at="2013-11-22"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml
new file mode 100644
index 00000000000..0a7b5aa0cf1
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/before.xml
@@ -0,0 +1,49 @@
+<dataset>
+
+ <!-- Should contains Simon B, simon and simon@codehaus.org -->
+ <users id="1" login="simon" name="Simon" active="[true]" email="simon@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <!-- Authors contains login, email and fab -> SCM accounts should contains only fab -->
+ <users id="2" login="fabrice" name="Fabrice" active="[true]" email="fabrice@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <!-- Authors contains only login and email -> Nothing to do -->
+ <users id="3" login="jb" name="Jean Baptiste" active="[true]" email="jb@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <!-- Only one author row -> Nothing to do -->
+ <users id="4" login="julien" name="Julien" active="[true]" email="julien@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <!-- Disable user -> Nothing to do -->
+ <users id="5" login="disable" name="Disable" active="[false]" email="disable@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <!-- 2 users with the same email -> Nothing to do -->
+ <users id="6" login="teryk" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+ <users id="7" login="teryk2" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+
+ <authors id="1" person_id="1" login="Simon B" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="2" person_id="1" login="simon" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="3" person_id="1" login="simon@codehaus.org" created_at="2015-01-01" updated_at="2015-01-01"/>
+
+ <authors id="4" person_id="2" login="fabrice@email.com" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="5" person_id="2" login="fab" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="6" person_id="2" login="fabrice" created_at="2015-01-01" updated_at="2015-01-01"/>
+
+ <authors id="7" person_id="3" login="jb@email.com" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="8" person_id="3" login="jb" created_at="2015-01-01" updated_at="2015-01-01"/>
+
+ <authors id="9" person_id="4" login="julien" created_at="2015-01-01" updated_at="2015-01-01"/>
+
+ <authors id="10" person_id="5" login="disable" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="11" person_id="5" login="Disable user" created_at="2015-01-01" updated_at="2015-01-01"/>
+
+ <authors id="12" person_id="6" login="teryk@email.com" created_at="2015-01-01" updated_at="2015-01-01"/>
+ <authors id="13" person_id="6" login="teryk_b" created_at="2015-01-01" updated_at="2015-01-01"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml
new file mode 100644
index 00000000000..3f2da7a6af2
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/no_authors.xml
@@ -0,0 +1,24 @@
+<dataset>
+
+ <users id="1" login="simon" name="Simon" active="[true]" email="simon@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <users id="2" login="fabrice" name="Fabrice" active="[true]" email="fabrice@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <users id="3" login="jb" name="Jean Baptiste" active="[true]" email="jb@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <users id="4" login="julien" name="Julien" active="[true]" email="julien@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <users id="5" login="disable" name="Disable" active="[false]" email="disable@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <users id="6" login="teryk" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+ <users id="7" login="teryk2" name="Teryk" active="[true]" email="teryk@email.com" scm_accounts="[null]"
+ created_at="1500000000000" updated_at="1500000000000"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql
new file mode 100644
index 00000000000..8dbd8b01ea9
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/CopyScmAccountsFromAuthorsToUsersTest/schema.sql
@@ -0,0 +1,22 @@
+CREATE TABLE "USERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "LOGIN" VARCHAR(255),
+ "NAME" VARCHAR(200),
+ "EMAIL" VARCHAR(100),
+ "CRYPTED_PASSWORD" VARCHAR(40),
+ "SALT" VARCHAR(40),
+ "REMEMBER_TOKEN" VARCHAR(500),
+ "REMEMBER_TOKEN_EXPIRES_AT" TIMESTAMP,
+ "ACTIVE" BOOLEAN DEFAULT TRUE,
+ "SCM_ACCOUNTS" VARCHAR(4000),
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT
+);
+
+CREATE TABLE "AUTHORS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PERSON_ID" INTEGER,
+ "LOGIN" VARCHAR(100),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml
new file mode 100644
index 00000000000..c0d5b5e59ec
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/before.xml
@@ -0,0 +1,52 @@
+<dataset>
+ <!-- new migration -->
+ <analysis_reports
+ id="1"
+ project_key="123456789-987654321"
+ snapshot_id="123"
+ report_data="data-project"
+ report_status="WORKING"
+ created_at="2014-09-25"
+ updated_at="2014-09-24"
+ started_at="2014-09-23"
+ finished_at="2014-09-22"
+ created_at_ms="[null]"
+ updated_at_ms="[null]"
+ started_at_ms="[null]"
+ finished_at_ms="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <analysis_reports
+ id="2"
+ project_key="123456789-987654321"
+ snapshot_id="123"
+ report_data="data-project"
+ report_status="WORKING"
+ created_at="2014-09-25"
+ updated_at="2014-09-24"
+ started_at="2014-09-23"
+ finished_at="2014-09-22"
+ created_at_ms="1500000000000"
+ updated_at_ms="1500000000000"
+ started_at_ms="1500000000000"
+ finished_at_ms="1500000000000"
+ />
+
+ <!-- NULL dates -->
+ <analysis_reports
+ id="3"
+ project_key="123456789-987654321"
+ snapshot_id="123"
+ report_data="data-project"
+ report_status="WORKING"
+ created_at="[null]"
+ updated_at="[null]"
+ started_at="[null]"
+ finished_at="[null]"
+ created_at_ms="[null]"
+ updated_at_ms="[null]"
+ started_at_ms="[null]"
+ finished_at_ms="[null]"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql
new file mode 100644
index 00000000000..c2187b6a747
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedAnalysisReportsLongDatesTest/schema.sql
@@ -0,0 +1,16 @@
+CREATE TABLE "ANALYSIS_REPORTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_KEY" VARCHAR(400) NOT NULL,
+ "PROJECT_NAME" VARCHAR(256) NULL,
+ "SNAPSHOT_ID" INTEGER NOT NULL,
+ "REPORT_STATUS" VARCHAR(20) NOT NULL,
+ "REPORT_DATA" BLOB(2147483647),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+ "STARTED_AT" TIMESTAMP,
+ "FINISHED_AT" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "UPDATED_AT_MS" BIGINT,
+ "STARTED_AT_MS" BIGINT,
+ "FINISHED_AT_MS" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml
new file mode 100644
index 00000000000..db9753d85be
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/before.xml
@@ -0,0 +1,28 @@
+<dataset>
+ <!-- new migration -->
+ <events
+ id="1"
+ created_at="2014-09-25"
+ created_at_ms="[null]"
+ event_date="2014-09-25"
+ event_date_ms="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the ones that are already fed with new dates -->
+ <events
+ id="2"
+ created_at="2014-09-25"
+ created_at_ms="1500000000"
+ event_date="2014-09-25"
+ event_date_ms="1500000000"
+ />
+
+ <!-- NULL dates -->
+ <events
+ id="3"
+ created_at="[null]"
+ created_at_ms="[null]"
+ event_date="[null]"
+ event_date_ms="[null]"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql
new file mode 100644
index 00000000000..71ac42d40ef
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedEventsLongDatesTest/schema.sql
@@ -0,0 +1,7 @@
+CREATE TABLE "EVENTS" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "EVENT_DATE" TIMESTAMP,
+ "EVENT_DATE_MS" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml
new file mode 100644
index 00000000000..b4e95d8a3ea
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/bad_data.xml
@@ -0,0 +1,8 @@
+<dataset>
+ <file_sources id="1" project_uuid="PROJECT_UUID" file_uuid="FILE1_UUID" created_at="1416238020000"
+ updated_at="1414770242000"
+ data="&quot;missing_escape_end"
+ binary_data="[null]"
+ line_hashes=""
+ data_hash=""/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml
new file mode 100644
index 00000000000..df9b36ac5a2
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/data.xml
@@ -0,0 +1,25 @@
+<dataset>
+ <!-- has data -->
+ <file_sources id="1" project_uuid="PROJECT_UUID" file_uuid="FILE1_UUID" created_at="1416238020000"
+ updated_at="1414770242000"
+ data="aef12a,alice,2014-04-25T12:34:56+0100,1,4,2,2,5,3,3,6,4,syntax_highlighting,symbol_refs,22,class Foo {&#13;&#10;abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,2, // Empty&#13;&#10;afb789,carol,2014-03-23T12:34:56+0100,0,,,0,,,0,,,,,,}&#13;&#10;afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,,&#13;&#10;"
+ binary_data="[null]"
+ line_hashes=""
+ data_hash=""/>
+
+ <!-- empty fields in CSV -->
+ <file_sources id="2" project_uuid="PROJECT_UUID" file_uuid="FILE2_UUID" created_at="1416238020000"
+ updated_at="1414770242000"
+ data=",,,,,,,,,,,,,,,&#10;,,,,,,,,,,,,,,,&#10;,,,,,,,,,,,,,,,&#10;,,,,,,,,,,,,,,,&#10;"
+ binary_data="[null]"
+ line_hashes=""
+ data_hash=""/>
+
+ <!-- null CSV -->
+ <file_sources id="3" project_uuid="PROJECT_UUID" file_uuid="FILE2_UUID" created_at="1416238020000"
+ updated_at="1414770242000"
+ data="[null]"
+ binary_data="[null]"
+ line_hashes=""
+ data_hash=""/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql
new file mode 100644
index 00000000000..5649f795864
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedFileSourcesBinaryDataTest/schema.sql
@@ -0,0 +1,12 @@
+CREATE TABLE "FILE_SOURCES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "FILE_UUID" VARCHAR(50) NOT NULL,
+ "LINE_HASHES" CLOB(2147483647),
+ "DATA" CLOB(2147483647),
+ "DATA_HASH" VARCHAR(50) NOT NULL,
+ "SRC_HASH" VARCHAR(50) NULL,
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL,
+ "BINARY_DATA" BINARY(167772150),
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml
new file mode 100644
index 00000000000..e8e59f0d053
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/before.xml
@@ -0,0 +1,31 @@
+<dataset>
+
+ <!-- new migration -->
+ <issue_changes id="1" kee="ABC-DEF" issue_key="ABC" user_login="[null]" change_type="[null]" change_data="[null]"
+ created_at="2013-05-18"
+ updated_at="2013-05-18"
+ issue_change_creation_date="2013-05-18"
+ created_at_ms="[null]"
+ updated_at_ms="[null]"
+ issue_change_creation_date_ms="[null]"/>
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <issue_changes id="2" kee="FGH-DEF" issue_key="FGH" user_login="[null]" change_type="[null]" change_data="[null]"
+ created_at="2013-05-18"
+ updated_at="2013-05-18"
+ issue_change_creation_date="2013-05-18"
+ created_at_ms="1500000000000"
+ updated_at_ms="1500000000000"
+ issue_change_creation_date_ms="1500000000000"/>
+
+ <!-- NULL dates -->
+ <issue_changes id="3" kee="MISSING-DEF" issue_key="MISSING" user_login="[null]" change_type="[null]"
+ change_data="[null]"
+ created_at="[null]"
+ updated_at="[null]"
+ issue_change_creation_date="[null]"
+ created_at_ms="[null]"
+ updated_at_ms="[null]"
+ issue_change_creation_date_ms="[null]"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql
new file mode 100644
index 00000000000..240e5cedf2d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueChangesLongDatesTest/schema.sql
@@ -0,0 +1,14 @@
+CREATE TABLE "ISSUE_CHANGES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(50),
+ "ISSUE_KEY" VARCHAR(50) NOT NULL,
+ "USER_LOGIN" VARCHAR(255),
+ "CHANGE_TYPE" VARCHAR(40),
+ "CHANGE_DATA" VARCHAR(16777215),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+ "ISSUE_CHANGE_CREATION_DATE" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "UPDATED_AT_MS" BIGINT,
+ "ISSUE_CHANGE_CREATION_DATE_MS" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml
new file mode 100644
index 00000000000..0422433b393
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/after-result.xml
@@ -0,0 +1,22 @@
+<dataset>
+ <issues id="1" kee="ABC"
+ component_id="100" component_uuid="COMPONENTUUID" root_component_id="10" project_uuid="PROJECTUUID"
+ resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10"
+ message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar"
+ action_plan_key="[null]" tags="[null]"
+ issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18"
+ created_at="1500000000000" updated_at="1500000000000"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with uuids -->
+ <issues id="2" kee="DEF"
+ component_id="101" component_uuid="ANOTHERUUID" root_component_id="11" project_uuid="ANOTHER2UUID"
+ resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10"
+ message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar"
+ action_plan_key="[null]" tags="[null]"
+ issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18"
+ created_at="1500000000000" updated_at="1500000000000"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml
new file mode 100644
index 00000000000..fbcd05d6875
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/before.xml
@@ -0,0 +1,30 @@
+<dataset>
+ <projects long_name="org.struts.RequestContext" id="100" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="COMPONENTUUID" project_uuid="PROJECTUUID" module_uuid="[null]" module_uuid_path="[null]"
+ name="RequestContext.java" root_id="2"
+ description="[null]" deprecated_kee="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java" created_at="2014-06-18"/>
+
+ <issues id="1" kee="ABC"
+ component_id="100" component_uuid="[null]" root_component_id="10" project_uuid="[null]"
+ resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10"
+ message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar"
+ action_plan_key="[null]" tags="[null]"
+ issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18"
+ created_at="1500000000000" updated_at="1500000000000"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with uuids -->
+ <issues id="2" kee="DEF"
+ component_id="101" component_uuid="ANOTHERUUID" root_component_id="11" project_uuid="ANOTHER2UUID"
+ resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]" author_login="[null]" checksum="[null]" effort_to_fix="[null]" technical_debt="10"
+ message="[null]" line="5000" rule_id="10" reporter="emmerik" issue_attributes="foo=bar"
+ action_plan_key="[null]" tags="[null]"
+ issue_creation_date="2013-05-18" issue_update_date="2013-05-18" issue_close_date="2013-05-18"
+ created_at="1500000000000" updated_at="1500000000000"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql
new file mode 100644
index 00000000000..b7157762feb
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueComponentUuidsTest/schema.sql
@@ -0,0 +1,52 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
+
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(50) UNIQUE NOT NULL,
+ "COMPONENT_ID" INTEGER NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50),
+ "ROOT_COMPONENT_ID" INTEGER,
+ "PROJECT_UUID" VARCHAR(50),
+ "RULE_ID" INTEGER,
+ "SEVERITY" VARCHAR(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" VARCHAR(4000),
+ "LINE" INTEGER,
+ "EFFORT_TO_FIX" DOUBLE,
+ "TECHNICAL_DEBT" INTEGER,
+ "STATUS" VARCHAR(20),
+ "RESOLUTION" VARCHAR(20),
+ "CHECKSUM" VARCHAR(1000),
+ "REPORTER" VARCHAR(255),
+ "ASSIGNEE" VARCHAR(255),
+ "AUTHOR_LOGIN" VARCHAR(255),
+ "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+ "ISSUE_ATTRIBUTES" VARCHAR(4000),
+ "TAGS" VARCHAR(4000),
+ "ISSUE_CREATION_DATE" TIMESTAMP,
+ "ISSUE_CLOSE_DATE" TIMESTAMP,
+ "ISSUE_UPDATE_DATE" TIMESTAMP,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml
new file mode 100644
index 00000000000..329a3f58f48
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/after-result.xml
@@ -0,0 +1,135 @@
+<dataset>
+
+ <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="10"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="tag1,tag2,tag3,tag4"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1418056380000"
+ />
+
+ <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="10"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ tags="polop,palap"
+ action_plan_key="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <issues id="3" kee="GHI" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="20"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="tag3,tag4"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1418056380000"
+ />
+
+ <issues id="4" kee="JKL" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="30"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="tag1,tag2"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1418056380000"
+ />
+
+ <issues id="5" kee="MNO" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="40"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <issues id="6" kee="PQR" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="666"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml
new file mode 100644
index 00000000000..63b14662f3d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/before.xml
@@ -0,0 +1,185 @@
+<dataset>
+
+ <rules id="10" plugin_rule_key="Rule1" plugin_name="xoo" name="Rule1" description="Rule1" status="READY" priority="1"
+ language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" plugin_config_key="[null]"
+ tags="tag3,tag4" system_tags="tag1,tag2"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+
+ <rules id="20" plugin_rule_key="Rule2" plugin_name="xoo" name="Rule2" description="Rule2" status="READY" priority="1"
+ language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" plugin_config_key="[null]"
+ tags="tag3,tag4" system_tags=""
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+
+ <rules id="30" plugin_rule_key="Rule3" plugin_name="xoo" name="Rule3" description="Rule3" status="READY" priority="1"
+ language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" plugin_config_key="[null]"
+ tags="[null]" system_tags="tag1,tag2"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+
+ <rules id="40" plugin_rule_key="Rule4" plugin_name="xoo" name="Rule4" description="Rule4" status="READY" priority="1"
+ language="xoo"
+ note_data="[null]" note_user_login="[null]" note_created_at="[null]" note_updated_at="[null]"
+ description_format="HTML" plugin_config_key="[null]"
+ tags="[null]" system_tags="[null]"
+ characteristic_id="[null]" default_characteristic_id="[null]"
+ remediation_function="[null]" default_remediation_function="[null]"
+ remediation_coeff="[null]" default_remediation_coeff="[null]"
+ remediation_offset="[null]" default_remediation_offset="[null]"
+ effort_to_fix_description="[null]"
+ is_template="[false]" template_id="[null]" created_at="2014-01-01" updated_at="2014-01-01"/>
+
+
+ <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="10"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="10"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ tags="polop,palap"
+ action_plan_key="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <issues id="3" kee="GHI" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="20"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <issues id="4" kee="JKL" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="30"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <issues id="5" kee="MNO" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="40"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+ <issues id="6" kee="PQR" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+ assignee="[null]"
+ author_login="[null]"
+ checksum="[null]"
+ effort_to_fix="[null]"
+ technical_debt="10"
+ message="[null]"
+ line="5000"
+ component_id="100"
+ root_component_id="10"
+ rule_id="666"
+ reporter="emmerik"
+ issue_attributes="foo=bar"
+ action_plan_key="[null]"
+ tags="[null]"
+ issue_creation_date="2013-05-18"
+ issue_update_date="2013-05-18"
+ issue_close_date="2013-05-18"
+ created_at="1500000000000"
+ updated_at="1500000000000"
+ />
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql
new file mode 100644
index 00000000000..a5ae2fca911
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssueTagsTest/schema.sql
@@ -0,0 +1,59 @@
+CREATE TABLE "RULES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PLUGIN_RULE_KEY" VARCHAR(200) NOT NULL,
+ "PLUGIN_NAME" VARCHAR(255) NOT NULL,
+ "DESCRIPTION" VARCHAR(16777215),
+ "DESCRIPTION_FORMAT" VARCHAR(20),
+ "PRIORITY" INTEGER,
+ "IS_TEMPLATE" BOOLEAN DEFAULT FALSE,
+ "TEMPLATE_ID" INTEGER,
+ "PLUGIN_CONFIG_KEY" VARCHAR(500),
+ "NAME" VARCHAR(200),
+ "STATUS" VARCHAR(40),
+ "LANGUAGE" VARCHAR(20),
+ "NOTE_DATA" CLOB(2147483647),
+ "NOTE_USER_LOGIN" VARCHAR(255),
+ "NOTE_CREATED_AT" TIMESTAMP,
+ "NOTE_UPDATED_AT" TIMESTAMP,
+ "CHARACTERISTIC_ID" INTEGER,
+ "DEFAULT_CHARACTERISTIC_ID" INTEGER,
+ "REMEDIATION_FUNCTION" VARCHAR(20),
+ "DEFAULT_REMEDIATION_FUNCTION" VARCHAR(20),
+ "REMEDIATION_COEFF" VARCHAR(20),
+ "DEFAULT_REMEDIATION_COEFF" VARCHAR(20),
+ "REMEDIATION_OFFSET" VARCHAR(20),
+ "DEFAULT_REMEDIATION_OFFSET" VARCHAR(20),
+ "EFFORT_TO_FIX_DESCRIPTION" VARCHAR(4000),
+ "TAGS" VARCHAR(4000),
+ "SYSTEM_TAGS" VARCHAR(4000),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(50) UNIQUE NOT NULL,
+ "COMPONENT_ID" INTEGER NOT NULL,
+ "ROOT_COMPONENT_ID" INTEGER,
+ "RULE_ID" INTEGER,
+ "SEVERITY" VARCHAR(10),
+ "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+ "MESSAGE" VARCHAR(4000),
+ "LINE" INTEGER,
+ "EFFORT_TO_FIX" DOUBLE,
+ "TECHNICAL_DEBT" INTEGER,
+ "STATUS" VARCHAR(20),
+ "RESOLUTION" VARCHAR(20),
+ "CHECKSUM" VARCHAR(1000),
+ "REPORTER" VARCHAR(255),
+ "ASSIGNEE" VARCHAR(255),
+ "AUTHOR_LOGIN" VARCHAR(255),
+ "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+ "ISSUE_ATTRIBUTES" VARCHAR(4000),
+ "TAGS" VARCHAR(4000),
+ "ISSUE_CREATION_DATE" TIMESTAMP,
+ "ISSUE_CLOSE_DATE" TIMESTAMP,
+ "ISSUE_UPDATE_DATE" TIMESTAMP,
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml
new file mode 100644
index 00000000000..be66fff5c0b
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/before.xml
@@ -0,0 +1,34 @@
+<dataset>
+ <!-- new migration -->
+ <issues
+ id="1"
+ issue_creation_date="2014-09-25"
+ issue_creation_date_ms="[null]"
+ issue_update_date="2014-09-25"
+ issue_update_date_ms="[null]"
+ issue_close_date="2014-09-25"
+ issue_close_date_ms="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <issues
+ id="2"
+ issue_creation_date="2014-09-25"
+ issue_creation_date_ms="1500000000"
+ issue_update_date="2014-09-25"
+ issue_update_date_ms="1500000000"
+ issue_close_date="2014-09-25"
+ issue_close_date_ms="1500000000"
+ />
+
+ <!-- NULL dates -->
+ <issues
+ id="3"
+ issue_creation_date="[null]"
+ issue_creation_date_ms="[null]"
+ issue_update_date="[null]"
+ issue_update_date_ms="[null]"
+ issue_close_date="[null]"
+ issue_close_date_ms="[null]"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql
new file mode 100644
index 00000000000..ab749851864
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedIssuesLongDatesTest/schema.sql
@@ -0,0 +1,9 @@
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "ISSUE_CREATION_DATE" TIMESTAMP,
+ "ISSUE_CREATION_DATE_MS" BIGINT,
+ "ISSUE_CLOSE_DATE" TIMESTAMP,
+ "ISSUE_CLOSE_DATE_MS" BIGINT,
+ "ISSUE_UPDATE_DATE" TIMESTAMP,
+ "ISSUE_UPDATE_DATE_MS" BIGINT,
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml
new file mode 100644
index 00000000000..e90f89769b1
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/before.xml
@@ -0,0 +1,28 @@
+<dataset>
+ <!-- new migration -->
+ <manual_measures
+ id="1"
+ created_at="2014-09-25"
+ created_at_ms="[null]"
+ updated_at="2014-09-25"
+ updated_at_ms="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the ones that are already fed with new dates -->
+ <manual_measures
+ id="2"
+ created_at="2014-09-25"
+ created_at_ms="1500000000"
+ updated_at="2014-09-25"
+ updated_at_ms="1500000000"
+ />
+
+ <!-- NULL dates -->
+ <manual_measures
+ id="3"
+ created_at="[null]"
+ created_at_ms="[null]"
+ updated_at="[null]"
+ updated_at_ms="[null]"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql
new file mode 100644
index 00000000000..c04fbbeb80e
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedManualMeasuresLongDatesTest/schema.sql
@@ -0,0 +1,7 @@
+CREATE TABLE "MANUAL_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "UPDATED_AT" TIMESTAMP,
+ "UPDATED_AT_MS" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml
new file mode 100644
index 00000000000..088fd0873f8
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/before.xml
@@ -0,0 +1,61 @@
+<dataset>
+ <!-- new migration -->
+ <snapshots
+ id="1"
+ project_id="1"
+ created_at="2014-09-25"
+ created_at_ms="[null]"
+ build_date="2014-09-25"
+ build_date_ms="[null]"
+ period1_date="2014-09-25"
+ period1_date_ms="[null]"
+ period2_date="2014-09-25"
+ period2_date_ms="[null]"
+ period3_date="2014-09-25"
+ period3_date_ms="[null]"
+ period4_date="2014-09-25"
+ period4_date_ms="[null]"
+ period5_date="2014-09-25"
+ period5_date_ms="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <snapshots
+ id="2"
+ project_id="1"
+ created_at="2014-09-25"
+ created_at_ms="1500000000"
+ build_date="2014-09-25"
+ build_date_ms="1500000000"
+ period1_date="2014-09-25"
+ period1_date_ms="1500000000"
+ period2_date="2014-09-25"
+ period2_date_ms="1500000000"
+ period3_date="2014-09-25"
+ period3_date_ms="1500000000"
+ period4_date="2014-09-25"
+ period4_date_ms="1500000000"
+ period5_date="2014-09-25"
+ period5_date_ms="1500000000"
+ />
+
+ <!-- NULL dates -->
+ <snapshots
+ id="3"
+ project_id="1"
+ created_at="[null]"
+ created_at_ms="[null]"
+ build_date="[null]"
+ build_date_ms="[null]"
+ period1_date="[null]"
+ period1_date_ms="[null]"
+ period2_date="[null]"
+ period2_date_ms="[null]"
+ period3_date="[null]"
+ period3_date_ms="[null]"
+ period4_date="[null]"
+ period4_date_ms="[null]"
+ period5_date="[null]"
+ period5_date_ms="[null]"
+ />
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql
new file mode 100644
index 00000000000..318169c0787
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedSnapshotsLongDatesTest/schema.sql
@@ -0,0 +1,18 @@
+CREATE TABLE "SNAPSHOTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "BUILD_DATE" TIMESTAMP,
+ "BUILD_DATE_MS" BIGINT,
+ "PROJECT_ID" INTEGER NOT NULL,
+ "PERIOD1_DATE" TIMESTAMP,
+ "PERIOD1_DATE_MS" BIGINT,
+ "PERIOD2_DATE" TIMESTAMP,
+ "PERIOD2_DATE_MS" BIGINT,
+ "PERIOD3_DATE" TIMESTAMP,
+ "PERIOD3_DATE_MS" BIGINT,
+ "PERIOD4_DATE" TIMESTAMP,
+ "PERIOD4_DATE_MS" BIGINT,
+ "PERIOD5_DATE" TIMESTAMP,
+ "PERIOD5_DATE_MS" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml
new file mode 100644
index 00000000000..a4b16c1fcd2
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/before.xml
@@ -0,0 +1,26 @@
+<dataset>
+
+ <users id="1" login="user1" name="User1" active="[true]"
+ created_at="2014-05-12"
+ updated_at="2014-05-13"
+ CREATED_AT_MS="[null]"
+ UPDATED_AT_MS="[null]"
+ />
+
+ <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+ <users id="2" login="user2" name="User2" active="[true]"
+ created_at="2014-05-12"
+ updated_at="2014-05-13"
+ CREATED_AT_MS="1500000000000"
+ UPDATED_AT_MS="1500000000000"
+ />
+
+ <!-- NULL dates -->
+ <users id="3" login="user3" name="User3" active="[true]"
+ created_at="[null]"
+ updated_at="[null]"
+ CREATED_AT_MS="[null]"
+ UPDATED_AT_MS="[null]"
+ />
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql
new file mode 100644
index 00000000000..ba24adf3a29
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/FeedUsersLongDatesTest/schema.sql
@@ -0,0 +1,15 @@
+CREATE TABLE "USERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "LOGIN" VARCHAR(255),
+ "NAME" VARCHAR(200),
+ "EMAIL" VARCHAR(100),
+ "CRYPTED_PASSWORD" VARCHAR(40),
+ "SALT" VARCHAR(40),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+ "CREATED_AT_MS" BIGINT,
+ "UPDATED_AT_MS" BIGINT,
+ "REMEMBER_TOKEN" VARCHAR(500),
+ "REMEMBER_TOKEN_EXPIRES_AT" TIMESTAMP,
+ "ACTIVE" BOOLEAN DEFAULT TRUE
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml
new file mode 100644
index 00000000000..66bbfaf90c1
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate-result.xml
@@ -0,0 +1,24 @@
+<dataset>
+
+ <projects id="100" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ authorization_updated_at="123456789"/>
+
+ <projects id="101" root_id="[null]" scope="PRJ" qualifier="BRC" kee="org.struts:struts-server" name="Struts Server"
+ description="the description" long_name="Apache Struts Server"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ authorization_updated_at="123456789"/>
+
+ <!-- Permissions on project -->
+ <user_roles id="1" user_id="200" resource_id="100" role="user"/>
+ <user_roles id="2" user_id="200" resource_id="100" role="admin"/>
+ <group_roles id="1" group_id="100" resource_id="100" role="codeviewer"/>
+
+ <!-- No more permissions on module -->
+
+ <!-- Global permissions -->
+ <user_roles id="10" user_id="200" resource_id="[null]" role="admin"/>
+ <group_roles id="10" group_id="200" resource_id="[null]" role="admin"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml
new file mode 100644
index 00000000000..a209fcf9025
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/migrate.xml
@@ -0,0 +1,29 @@
+<dataset>
+
+ <projects id="100" uuid="ABCD" module_uuid="[null]" project_uuid="ABCD" module_uuid_path=".ABCD." root_id="[null]"
+ scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts" description="the description"
+ long_name="Apache Struts"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ authorization_updated_at="123456789"/>
+
+ <projects id="101" uuid="BCDE" module_uuid="ABCD" project_uuid="ABCD" module_uuid_path=".ABCD.BCDE." root_id="100"
+ scope="PRJ" qualifier="BRC" kee="org.struts:struts-server" name="Struts Server"
+ description="the description" long_name="Apache Struts Server"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ authorization_updated_at="123456789"/>
+
+ <!-- Permissions on project -->
+ <user_roles id="1" user_id="200" resource_id="100" role="user"/>
+ <user_roles id="2" user_id="200" resource_id="100" role="admin"/>
+ <group_roles id="1" group_id="100" resource_id="100" role="codeviewer"/>
+
+ <!-- Permissions on module : should be deleted -->
+ <user_roles id="3" user_id="200" resource_id="101" role="user"/>
+ <user_roles id="4" user_id="200" resource_id="101" role="admin"/>
+ <group_roles id="2" group_id="100" resource_id="101" role="codeviewer"/>
+
+ <!-- Global permissions -->
+ <user_roles id="10" user_id="200" resource_id="[null]" role="admin"/>
+ <group_roles id="10" group_id="200" resource_id="[null]" role="admin"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml
new file mode 100644
index 00000000000..8a842e7a734
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/nothing_to_do_when_already_migrated.xml
@@ -0,0 +1,22 @@
+<dataset>
+
+ <projects id="100" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ authorization_updated_at="123456789"/>
+
+ <projects id="101" root_id="[null]" scope="PRJ" qualifier="BRC" kee="org.struts:struts-server" name="Struts Server"
+ description="the description" long_name="Apache Struts Server"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ authorization_updated_at="123456789"/>
+
+ <!-- Permissions on project -->
+ <user_roles id="1" user_id="200" resource_id="100" role="user"/>
+ <user_roles id="2" user_id="200" resource_id="100" role="admin"/>
+ <group_roles id="1" group_id="100" resource_id="100" role="codeviewer"/>
+
+ <!-- Global permissions -->
+ <user_roles id="10" user_id="200" resource_id="[null]" role="admin"/>
+ <group_roles id="10" group_id="200" resource_id="[null]" role="admin"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql
new file mode 100644
index 00000000000..b291cf0beea
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RemovePermissionsOnModulesMigrationTest/schema.sql
@@ -0,0 +1,49 @@
+CREATE TABLE "USER_ROLES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "USER_ID" INTEGER,
+ "RESOURCE_ID" INTEGER,
+ "ROLE" VARCHAR(64) NOT NULL
+);
+
+CREATE INDEX "USER_ROLES_RESOURCE" ON "USER_ROLES" ("RESOURCE_ID");
+
+CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES" ("USER_ID");
+
+CREATE TABLE "GROUP_ROLES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "GROUP_ID" INTEGER,
+ "RESOURCE_ID" INTEGER,
+ "ROLE" VARCHAR(64) NOT NULL
+);
+
+CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES" ("RESOURCE_ID");
+
+CREATE INDEX "GROUP_ROLES_GROUP" ON "GROUP_ROLES" ("GROUP_ID");
+
+CREATE INDEX "GROUP_ROLES_ROLE" ON "GROUP_ROLES" ("ROLE");
+
+CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES" ("GROUP_ID", "RESOURCE_ID", "ROLE");
+
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
+
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml
new file mode 100644
index 00000000000..a3dc90896d3
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute-result.xml
@@ -0,0 +1,68 @@
+<dataset>
+
+ <!-- Not updated, no concerned field -->
+ <issue_filters
+ id="1"
+ name="No concerned field"
+ user_login="stephane"
+ shared="[true]"
+ description="no not touch"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <!-- Not updated, projectUuids is left as is -->
+ <issue_filters
+ id="2"
+ name="Has projects"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|asc=true|projectUuids=ABC"
+ created_at="2013-06-10"
+ updated_at="2013-06-10 00:00:00.0"/>
+
+ <!-- componentUuids replaced by fileUuids -->
+ <issue_filters
+ id="3"
+ name="Has components"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="fileUuids=ABC|statuses=OPEN|sort=SEVERITY|asc=true"
+ created_at="2013-06-10"
+ updated_at="2014-10-29 00:00:00.0"/>
+
+ <!-- componentRootUuids replaced by moduleUuids -->
+ <issue_filters
+ id="4"
+ name="Has componentRoots"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|asc=true|moduleUuids=ABC"
+ created_at="2013-06-10"
+ updated_at="2014-10-29 00:00:00.0"/>
+
+ <!-- componentRootUuids replaced by moduleUuids (in the middle of the string) -->
+ <issue_filters
+ id="5"
+ name="Has projects"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|moduleUuids=ABC|asc=true"
+ created_at="2013-06-10"
+ updated_at="2014-10-29 00:00:00.0"/>
+
+ <!-- componentUuidss replaced by fileUuids, componentRootUuids replaced by moduleUuids -->
+ <issue_filters
+ id="6"
+ name="Has all parameters"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|fileUuids=BCD|moduleUuids=ABC|projectUuids=CDE|asc=true"
+ created_at="2013-06-10"
+ updated_at="2014-10-29 00:00:00.0"/>
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml
new file mode 100644
index 00000000000..971334c5066
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/execute.xml
@@ -0,0 +1,69 @@
+<dataset>
+
+ <!-- Not updated, no concerned field -->
+ <issue_filters
+ id="1"
+ name="No concerned field"
+ user_login="stephane"
+ shared="[true]"
+ description="no not touch"
+ data="projectUuids=ABCD"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <!-- Not updated, projectUuids is left as is -->
+ <issue_filters
+ id="2"
+ name="Has projects"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|asc=true|projectUuids=ABC"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <!-- componentUuids replaced by fileUuids -->
+ <issue_filters
+ id="3"
+ name="Has components"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="componentUuids=ABC|statuses=OPEN|sort=SEVERITY|asc=true"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <!-- componentRootUuids replaced by moduleUuids -->
+ <issue_filters
+ id="4"
+ name="Has componentRoots"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|asc=true|componentRootUuids=ABC"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <!-- componentRootUuids replaced by moduleUuids (in the middle of the string) -->
+ <issue_filters
+ id="5"
+ name="Has projects"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|componentRootUuids=ABC|asc=true"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+ <!-- componentUuidss replaced by fileUuids, componentRootUuids replaced by moduleUuids -->
+ <issue_filters
+ id="6"
+ name="Has all parameters"
+ user_login="michael"
+ shared="[false]"
+ description="to be updated"
+ data="statuses=OPEN|sort=SEVERITY|componentUuids=BCD|componentRootUuids=ABC|projectUuids=CDE|asc=true"
+ created_at="2013-06-10"
+ updated_at="2013-06-10"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql
new file mode 100644
index 00000000000..0627153a62d
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/RenameComponentRelatedParamsInIssueFiltersMigrationTest/schema.sql
@@ -0,0 +1,10 @@
+CREATE TABLE "ISSUE_FILTERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(100) NOT NULL,
+ "SHARED" BOOLEAN NOT NULL DEFAULT FALSE,
+ "USER_LOGIN" VARCHAR(255),
+ "DESCRIPTION" VARCHAR(4000),
+ "DATA" CLOB(2147483647),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml
new file mode 100644
index 00000000000..85f8eb4b928
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components-result.xml
@@ -0,0 +1,100 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD."
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH."
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- sub module, already has dots: only itself appended -->
+ <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" deprecated_kee="org.struts:struts-data"
+ uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH.FGHI."
+ scope="PRJ" qualifier="BRC" long_name="Struts Data"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- directory -->
+ <projects id="4" root_id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ deprecated_kee="org.struts:struts-core:src/org/struts"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI."
+ name="src/org/struts" long_name="org.struts"
+ description="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- file -->
+ <projects id="5" root_id="3" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI."
+ name="RequestContext.java" long_name="org.struts.RequestContext"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- view -->
+ <projects id="6" root_id="[null]" scope="PRJ" qualifier="VW" kee="Teams" name="Teams" deprecated_kee="Teams"
+ uuid="MEAT" project_uuid="MEAT" module_uuid="[null]" module_uuid_path=".MEAT."
+ description="the description" long_name="Teams"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- sub-view -->
+ <projects id="7" root_id="6" scope="PRJ" qualifier="SVW" kee="Platform_Team" name="Platform Team"
+ deprecated_kee="Platform_Team"
+ uuid="PLAT" project_uuid="MEAT" module_uuid="MEAT" module_uuid_path=".MEAT.PLAT."
+ description="the description" long_name="Platform Team"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- view technical project - unchanged -->
+ <projects id="8" root_id="6" scope="FIL" qualifier="TRK" kee="Platform_Team:sonarqube" name="SonarQube"
+ deprecated_kee="Platform_Team:sonarqube"
+ uuid="SNQB" project_uuid="PLAT" module_uuid="PLAT" module_uuid_path=".MEAT.PLAT."
+ description="the description" long_name="Platform Team"
+ enabled="[true]" language="[null]" copy_resource_id="42" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- root project already has dots, appending itself -->
+ <projects id="9" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample"
+ deprecated_kee="org.sonar:sample"
+ uuid="WDOT" project_uuid="WDOT" module_uuid="[null]" module_uuid_path=".WDOT."
+ description="the description" long_name="Sample"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- root project with module_uuid_path NULL -->
+ <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample"
+ deprecated_kee="org.sonar:sample"
+ uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path=".DCBA."
+ description="the description" long_name="Sample"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- developer -->
+ <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin.skywalker" name="Anakin Skywalker"
+ deprecated_kee="DEV:anakin.skywalker"
+ uuid="VADR" project_uuid="VADR" module_uuid="[null]" module_uuid_path=".VADR."
+ description="the description" long_name="Anakin Skywalker"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="1" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- developer technical project, with dots - unchanged -->
+ <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin.skywalker:Executor"
+ name="Executor Star Dreadnaught" deprecated_kee="DEV:anakin.skywalker:Executor"
+ uuid="EXCT" project_uuid="VADR" module_uuid="VADR" module_uuid_path=".VADR."
+ description="the description" long_name="Executor Star Dreadnaught"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml
new file mode 100644
index 00000000000..ede863b4724
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/migrate_components.xml
@@ -0,0 +1,100 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- sub module, already has dots: only itself appended -->
+ <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" deprecated_kee="org.struts:struts-data"
+ uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
+ scope="PRJ" qualifier="BRC" long_name="Struts Data"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- directory -->
+ <projects id="4" root_id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ deprecated_kee="org.struts:struts-core:src/org/struts"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI"
+ name="src/org/struts" long_name="org.struts"
+ description="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- file -->
+ <projects id="5" root_id="3" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI"
+ name="RequestContext.java" long_name="org.struts.RequestContext"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- view -->
+ <projects id="6" root_id="[null]" scope="PRJ" qualifier="VW" kee="Teams" name="Teams" deprecated_kee="Teams"
+ uuid="MEAT" project_uuid="MEAT" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Teams"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- sub-view -->
+ <projects id="7" root_id="6" scope="PRJ" qualifier="SVW" kee="Platform_Team" name="Platform Team"
+ deprecated_kee="Platform_Team"
+ uuid="PLAT" project_uuid="MEAT" module_uuid="MEAT" module_uuid_path="MEAT"
+ description="the description" long_name="Platform Team"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- view technical project, already has dots - unchanged -->
+ <projects id="8" root_id="6" scope="FIL" qualifier="TRK" kee="Platform_Team:sonarqube" name="SonarQube"
+ deprecated_kee="Platform_Team:sonarqube"
+ uuid="SNQB" project_uuid="PLAT" module_uuid="PLAT" module_uuid_path=".MEAT.PLAT."
+ description="the description" long_name="Platform Team"
+ enabled="[true]" language="[null]" copy_resource_id="42" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- root project already has dots, appending itself -->
+ <projects id="9" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample"
+ deprecated_kee="org.sonar:sample"
+ uuid="WDOT" project_uuid="WDOT" module_uuid="[null]" module_uuid_path="."
+ description="the description" long_name="Sample"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- root project with module_uuid_path NULL -->
+ <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample"
+ deprecated_kee="org.sonar:sample"
+ uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Sample"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- developer -->
+ <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin.skywalker" name="Anakin Skywalker"
+ deprecated_kee="DEV:anakin.skywalker"
+ uuid="VADR" project_uuid="VADR" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Anakin Skywalker"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="1" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- developer technical project, with dots - unchanged -->
+ <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin.skywalker:Executor"
+ name="Executor Star Dreadnaught" deprecated_kee="DEV:anakin.skywalker:Executor"
+ uuid="EXCT" project_uuid="VADR" module_uuid="VADR" module_uuid_path=".VADR."
+ description="the description" long_name="Executor Star Dreadnaught"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml
new file mode 100644
index 00000000000..547192c2bbf
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/not_migrate_already_migrated_components.xml
@@ -0,0 +1,100 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD."
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH."
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- sub module -->
+ <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" deprecated_kee="org.struts:struts-data"
+ uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH.FGHI."
+ scope="PRJ" qualifier="BRC" long_name="Struts Data"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- directory -->
+ <projects id="4" root_id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ deprecated_kee="org.struts:struts-core:src/org/struts"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI."
+ name="src/org/struts" long_name="org.struts"
+ description="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- file -->
+ <projects id="5" root_id="3" scope="FIL" qualifier="FIL"
+ kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path=".ABCD.EFGH.FGHI."
+ name="RequestContext.java" long_name="org.struts.RequestContext"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+ path="src/org/struts/RequestContext.java"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- view -->
+ <projects id="6" root_id="[null]" scope="PRJ" qualifier="VW" kee="Teams" name="Teams" deprecated_kee="Teams"
+ uuid="MEAT" project_uuid="MEAT" module_uuid="[null]" module_uuid_path=".MEAT."
+ description="the description" long_name="Teams"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- sub-view -->
+ <projects id="7" root_id="[null]" scope="PRJ" qualifier="SVW" kee="Platform_Team" name="Platform Team"
+ deprecated_kee="Platform_Team"
+ uuid="PLAT" project_uuid="MEAT" module_uuid="MEAT" module_uuid_path=".MEAT.PLAT."
+ description="the description" long_name="Platform Team"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- view technical project, already has dots - unchanged -->
+ <projects id="8" root_id="[null]" scope="FIL" qualifier="TRK" kee="Platform_Team:sonarqube" name="SonarQube"
+ deprecated_kee="Platform_Team:sonarqube"
+ uuid="SNQB" project_uuid="PLAT" module_uuid="PLAT" module_uuid_path=".MEAT.PLAT."
+ description="the description" long_name="Platform Team"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- root project already has dots, appending itself -->
+ <projects id="9" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample"
+ deprecated_kee="org.sonar:sample"
+ uuid="WDOT" project_uuid="WDOT" module_uuid="[null]" module_uuid_path=".WDOT."
+ description="the description" long_name="Sample"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- root project with module_uuid_path NULL -->
+ <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.sonar:sample" name="Sample"
+ deprecated_kee="org.sonar:sample"
+ uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path=".DCBA."
+ description="the description" long_name="Sample"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- developer -->
+ <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin.skywalker" name="Anakin Skywalker"
+ deprecated_kee="DEV:anakin.skywalker"
+ uuid="VADR" project_uuid="VADR" module_uuid="[null]" module_uuid_path=".VADR."
+ description="the description" long_name="Anakin Skywalker"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="1" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- developer technical project, with dots - unchanged -->
+ <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin.skywalker:Executor"
+ name="Executor Star Dreadnaught" deprecated_kee="DEV:anakin.skywalker:Executor"
+ uuid="EXCT" project_uuid="VADR" module_uuid="VADR" module_uuid_path=".VADR."
+ description="the description" long_name="Executor Star Dreadnaught"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql
new file mode 100644
index 00000000000..b7307a0902a
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v51/UpdateProjectsModuleUuidPathTest/schema.sql
@@ -0,0 +1,22 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql
new file mode 100644
index 00000000000..6fa4c32a970
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumnTest/schema.sql
@@ -0,0 +1,11 @@
+CREATE TABLE "MANUAL_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "METRIC_ID" INTEGER NOT NULL,
+ "RESOURCE_ID" INTEGER,
+ "VALUE" DOUBLE,
+ "TEXT_VALUE" VARCHAR(4000),
+ "USER_LOGIN" VARCHAR(255),
+ "DESCRIPTION" VARCHAR(4000),
+ "CREATED_AT" BIGINT,
+ "UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml
new file mode 100644
index 00000000000..2f6d90c92cb
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate-result.xml
@@ -0,0 +1,6 @@
+<dataset>
+
+ <events id="1" name="1.0" resource_id="1" component_uuid="ABCD" snapshot_id="1000" category="Version"
+ event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml
new file mode 100644
index 00000000000..38cd3d20e3a
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/migrate.xml
@@ -0,0 +1,13 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <events id="1" name="1.0" resource_id="1" component_uuid="[null]" snapshot_id="1000" category="Version"
+ event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml
new file mode 100644
index 00000000000..afecdb23d15
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/not_migrate_already_migrated_data.xml
@@ -0,0 +1,13 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <events id="1" name="1.0" resource_id="1" component_uuid="ABCD" snapshot_id="1000" category="Version"
+ event_date="1225630680000" created_at="1225630680000" description="" event_data="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql
new file mode 100644
index 00000000000..e4ca540f2f2
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedEventsComponentUuidTest/schema.sql
@@ -0,0 +1,35 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
+
+CREATE TABLE "EVENTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(400),
+ "RESOURCE_ID" INTEGER,
+ "COMPONENT_UUID" VARCHAR(50),
+ "SNAPSHOT_ID" INTEGER,
+ "CATEGORY" VARCHAR(50),
+ "EVENT_DATE" BIGINT NOT NULL,
+ "CREATED_AT" BIGINT NOT NULL,
+ "DESCRIPTION" VARCHAR(4000),
+ "EVENT_DATA" VARCHAR(4000)
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml
new file mode 100644
index 00000000000..3788fbf38ef
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate-result.xml
@@ -0,0 +1,10 @@
+<dataset>
+
+ <file_sources id="1" project_uuid="project-1" file_uuid="file-1" data_type="SOURCE" created_at="123456789"
+ updated_at="456456456"/>
+ <file_sources id="2" project_uuid="project-2" file_uuid="file-2" data_type="SOURCE" created_at="123456789"
+ updated_at="456456456"/>
+ <file_sources id="3" project_uuid="project-3" file_uuid="file-3" data_type="SOURCE" created_at="123456789"
+ updated_at="456456456"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml
new file mode 100644
index 00000000000..2282a9bb4c0
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/migrate.xml
@@ -0,0 +1,10 @@
+<dataset>
+
+ <file_sources id="1" project_uuid="project-1" file_uuid="file-1" data_type="[null]" created_at="123456789"
+ updated_at="456456456"/>
+ <file_sources id="2" project_uuid="project-2" file_uuid="file-2" data_type="SOURCE" created_at="123456789"
+ updated_at="456456456"/>
+ <file_sources id="3" project_uuid="project-3" file_uuid="file-3" data_type="[null]" created_at="123456789"
+ updated_at="456456456"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql
new file mode 100644
index 00000000000..84eb7749817
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedFileSourcesDataTypeTest/schema.sql
@@ -0,0 +1,8 @@
+CREATE TABLE "FILE_SOURCES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "FILE_UUID" VARCHAR(50) NOT NULL,
+ "DATA_TYPE" VARCHAR(20),
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml
new file mode 100644
index 00000000000..2dd0252cb3c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate-result.xml
@@ -0,0 +1,6 @@
+<dataset>
+
+ <manual_measures id="1" resource_id="10" component_uuid="ABCD"/>
+ <manual_measures id="2" resource_id="20" component_uuid="EFGH"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml
new file mode 100644
index 00000000000..2a36c383c69
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/migrate.xml
@@ -0,0 +1,9 @@
+<dataset>
+
+ <projects id="10" uuid="ABCD"/>
+ <projects id="20" uuid="EFGH"/>
+
+ <manual_measures id="1" resource_id="10" component_uuid="[null]"/>
+ <manual_measures id="2" resource_id="20" component_uuid="EFGH"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql
new file mode 100644
index 00000000000..bc2c66dc238
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedManualMeasuresComponentUuidTest/schema.sql
@@ -0,0 +1,10 @@
+CREATE TABLE "MANUAL_MEASURES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "RESOURCE_ID" INTEGER,
+ "COMPONENT_UUID" VARCHAR(50),
+);
+
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "UUID" VARCHAR(50),
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml
new file mode 100644
index 00000000000..dd63f7edb36
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate-result.xml
@@ -0,0 +1,9 @@
+<dataset>
+
+ <metrics id="1" user_managed="[true]" optimized_best_value="[false]" hidden="[false]"
+ delete_historical_data="[false]"/>
+ <metrics id="2" user_managed="[false]" optimized_best_value="[true]" hidden="[true]" delete_historical_data="[true]"/>
+ <metrics id="3" user_managed="[false]" optimized_best_value="[false]" hidden="[false]"
+ delete_historical_data="[false]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml
new file mode 100644
index 00000000000..7fee0be9b77
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/migrate.xml
@@ -0,0 +1,7 @@
+<dataset>
+
+ <metrics id="1" user_managed="[true]" optimized_best_value="[null]" hidden="[null]" delete_historical_data="[null]"/>
+ <metrics id="2" user_managed="[false]" optimized_best_value="[true]" hidden="[true]" delete_historical_data="[true]"/>
+ <metrics id="3" user_managed="[false]" optimized_best_value="[null]" hidden="[null]" delete_historical_data="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql
new file mode 100644
index 00000000000..d65487d7677
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedMetricsBooleansTest/schema.sql
@@ -0,0 +1,7 @@
+CREATE TABLE "METRICS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "USER_MANAGED" BOOLEAN DEFAULT FALSE,
+ "OPTIMIZED_BEST_VALUE" BOOLEAN,
+ "HIDDEN" BOOLEAN,
+ "DELETE_HISTORICAL_DATA" BOOLEAN
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml
new file mode 100644
index 00000000000..e46458a32e7
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate-result.xml
@@ -0,0 +1,28 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Both links now contains component uuid-->
+ <project_links id="1" project_id="1" component_uuid="ABCD" link_type="homepage" name="Home"
+ href="http://www.struts.org"/>
+ <project_links id="2" project_id="1" component_uuid="ABCD" link_type="scm" name="Sources"
+ href="https://github.com/Struts"/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Link now contains component uuid-->
+ <project_links id="3" project_id="2" component_uuid="EFGH" link_type="scm" name="Sources"
+ href="https://github.com/Struts/struts-core"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml
new file mode 100644
index 00000000000..a1de6ecdf02
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/migrate.xml
@@ -0,0 +1,26 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <project_links id="1" project_id="1" component_uuid="[null]" link_type="homepage" name="Home"
+ href="http://www.struts.org"/>
+ <project_links id="2" project_id="1" component_uuid="[null]" link_type="scm" name="Sources"
+ href="https://github.com/Struts"/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <project_links id="3" project_id="2" component_uuid="[null]" link_type="scm" name="Sources"
+ href="https://github.com/Struts/struts-core"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml
new file mode 100644
index 00000000000..fc7f64f6e9c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/not_migrate_already_migrated_data.xml
@@ -0,0 +1,28 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Links already contains component uuid-->
+ <project_links id="1" project_id="1" component_uuid="ABCD" link_type="homepage" name="Home"
+ href="http://www.struts.org"/>
+ <project_links id="2" project_id="1" component_uuid="ABCD" link_type="scm" name="Sources"
+ href="https://github.com/Struts"/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" deprecated_kee="org.struts:struts-core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD"
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Link already contains component uuid-->
+ <project_links id="3" project_id="2" component_uuid="EFGH" link_type="scm" name="Sources"
+ href="https://github.com/Struts/struts-core"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql
new file mode 100644
index 00000000000..f04590ffebd
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/FeedProjectLinksComponentUuidTest/schema.sql
@@ -0,0 +1,31 @@
+CREATE TABLE "PROJECT_LINKS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_ID" INTEGER NOT NULL,
+ "COMPONENT_UUID" VARCHAR(50),
+ "LINK_TYPE" VARCHAR(20),
+ "NAME" VARCHAR(128),
+ "HREF" VARCHAR(2048) NOT NULL
+);
+
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml
new file mode 100644
index 00000000000..2a5da2677cc
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate-result.xml
@@ -0,0 +1,29 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Default Java profile, will be set as default -->
+ <rules_profiles id="1" name="Java One" language="java" parent_kee="[null]" kee="java-one" is_default="[true]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <rules_profiles id="2" name="Java Two" language="java" parent_kee="[null]" kee="java-two" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <rules_profiles id="3" name="Php One" language="php" parent_kee="[null]" kee="php-one" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <rules_profiles id="4" name="Cobol One" language="cbl" parent_kee="[null]" kee="cobol-one" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <!-- Unmodified property -->
+ <properties id="1" prop_key="polop.palap" text_value="Untouched" resource_id="[null]" user_id="[null]"/>
+
+ <!-- Project 'Struts' uses profile 'Java Two', moved to association table -->
+ <project_qprofiles id="1" project_uuid="ABCD" profile_key="java-two"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml
new file mode 100644
index 00000000000..98849222aa9
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/migrate.xml
@@ -0,0 +1,41 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Default Java profile, will be set as default -->
+ <rules_profiles id="1" name="Java One" language="java" parent_kee="[null]" kee="java-one" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <rules_profiles id="2" name="Java Two" language="java" parent_kee="[null]" kee="java-two" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <rules_profiles id="3" name="Php One" language="php" parent_kee="[null]" kee="php-one" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <rules_profiles id="4" name="Cobol One" language="cbl" parent_kee="[null]" kee="cobol-one" is_default="[false]"
+ created_at="[null]" updated_at="[null]" rules_updated_at="[null]"/>
+
+ <!-- Unmodified property -->
+ <properties id="1" prop_key="polop.palap" text_value="Untouched" resource_id="[null]" user_id="[null]"/>
+
+ <!-- Default Java profile, will be set as default -->
+ <properties id="2" prop_key="sonar.profile.java" text_value="Java One" resource_id="[null]" user_id="[null]"/>
+
+ <!-- Project 'Struts' uses profile 'Java Two', will be moved to association table -->
+ <properties id="3" prop_key="sonar.profile.java" text_value="Java Two" resource_id="1" user_id="[null]"/>
+
+ <!-- Property on unknown language, will be ignored -->
+ <properties id="4" prop_key="sonar.profile.xoo" text_value="Xoo One" resource_id="[null]" user_id="[null]"/>
+
+ <!-- Property on unknown profile, will be ignored -->
+ <properties id="5" prop_key="sonar.profile.php" text_value="Php Two" resource_id="[null]" user_id="[null]"/>
+
+ <!-- Property on unknown project, will be ignored -->
+ <properties id="6" prop_key="sonar.profile.php" text_value="Php One" resource_id="2" user_id="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql
new file mode 100644
index 00000000000..004569aacfe
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/MoveProjectProfileAssociationTest/schema.sql
@@ -0,0 +1,48 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
+
+CREATE TABLE "RULES_PROFILES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(100) NOT NULL,
+ "LANGUAGE" VARCHAR(20),
+ "KEE" VARCHAR(255) NOT NULL,
+ "PARENT_KEE" VARCHAR(255),
+ "RULES_UPDATED_AT" VARCHAR(100),
+ "IS_DEFAULT" BOOLEAN NOT NULL DEFAULT FALSE,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "PROPERTIES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROP_KEY" VARCHAR(512),
+ "RESOURCE_ID" INTEGER,
+ "TEXT_VALUE" CLOB(2147483647),
+ "USER_ID" INTEGER
+);
+
+CREATE TABLE "PROJECT_QPROFILES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(255) NOT NULL
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml
new file mode 100644
index 00000000000..8c9f5d38dfb
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries-result.xml
@@ -0,0 +1,17 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Removed -->
+ <!--<projects id="2" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library" name="org.hamcrest:hamcrest-library"-->
+ <!--uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"-->
+ <!--description="[null]" long_name="org.hamcrest:hamcrest-library"-->
+ <!--enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"-->
+ <!--created_at="2014-06-18" />-->
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml
new file mode 100644
index 00000000000..59392a2b98c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/remove_libraries.xml
@@ -0,0 +1,19 @@
+<dataset>
+
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ deprecated_kee="org.struts:struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=""
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ created_at="2008-12-02 13:58:00.00" authorization_updated_at="[null]"/>
+
+ <!-- Should be removed -->
+ <projects id="2" root_id="[null]" scope="PRJ" qualifier="LIB" kee="org.hamcrest:hamcrest-library"
+ name="org.hamcrest:hamcrest-library"
+ uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+ description="[null]" long_name="org.hamcrest:hamcrest-library"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]"
+ deprecated_kee="[null]"
+ created_at="2014-06-18"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql
new file mode 100644
index 00000000000..b7307a0902a
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveComponentLibrariesTest/schema.sql
@@ -0,0 +1,22 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "ROOT_ID" INTEGER,
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "MODULE_UUID" VARCHAR(50),
+ "MODULE_UUID_PATH" VARCHAR(4000),
+ "NAME" VARCHAR(256),
+ "DESCRIPTION" VARCHAR(2000),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "DEPRECATED_KEE" VARCHAR(400),
+ "PATH" VARCHAR(2000),
+ "LANGUAGE" VARCHAR(20),
+ "COPY_RESOURCE_ID" INTEGER,
+ "LONG_NAME" VARCHAR(256),
+ "PERSON_ID" INTEGER,
+ "CREATED_AT" TIMESTAMP,
+ "AUTHORIZATION_UPDATED_AT" BIGINT
+);
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml
new file mode 100644
index 00000000000..a103099ddf4
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component-result.xml
@@ -0,0 +1,20 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/>
+
+ <!-- module -->
+ <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/>
+
+ <!-- sub modules -->
+ <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/>
+
+ <!-- directories -->
+ <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[true]"/>
+
+ <!-- files -->
+ <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[true]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml
new file mode 100644
index 00000000000..893efe4fd15
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_enable_component.xml
@@ -0,0 +1,31 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/>
+
+ <!-- module -->
+ <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/>
+
+ <!-- sub modules -->
+ <projects id="20" uuid="SUB_MODULE_1" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+ <!-- Only this component must be kept, as it's enabled -->
+ <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/>
+ <projects id="22" uuid="SUB_MODULE_3" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+
+ <!-- directories -->
+ <projects id="30" uuid="DIRECTORY_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+ <!-- Only this component must be kept, as it's enabled -->
+ <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[true]"/>
+
+ <!-- files -->
+ <!-- Only this component must be kept, as it's enabled -->
+ <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[true]"/>
+ <projects id="41" uuid="FILE_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml
new file mode 100644
index 00000000000..cd86088d452
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component-result.xml
@@ -0,0 +1,20 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/>
+
+ <!-- module -->
+ <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/>
+
+ <!-- sub modules -->
+ <projects id="22" uuid="SUB_MODULE_3" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+
+ <!-- directories -->
+ <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+
+ <!-- files -->
+ <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml
new file mode 100644
index 00000000000..72f1bea892e
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/keep_last_component.xml
@@ -0,0 +1,31 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/>
+
+ <!-- module -->
+ <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/>
+
+ <!-- sub modules -->
+ <projects id="20" uuid="SUB_MODULE_1" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+ <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+ <!-- Only this component must be kept, as it's the last one -->
+ <projects id="22" uuid="SUB_MODULE_3" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+
+ <!-- directories -->
+ <projects id="30" uuid="DIRECTORY_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+ <!-- Only this component must be kept, as it's the last one -->
+ <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+
+ <!-- files -->
+ <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <projects id="41" uuid="FILE_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <!-- Only this component must be kept, as it's the last one -->
+ <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml
new file mode 100644
index 00000000000..75d7c73b2f6
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate-result.xml
@@ -0,0 +1,26 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/>
+ <issues id="1" component_uuid="PROJECT" project_uuid="PROJECT"/>
+
+ <!-- module -->
+ <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/>
+
+ <!-- sub module -->
+ <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/>
+ <issues id="20" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/>
+ <issues id="21" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/>
+ <issues id="22" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/>
+
+ <!-- removed directory -->
+ <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+
+ <!-- removed file -->
+ <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <issues id="40" component_uuid="FILE_3" project_uuid="PROJECT"/>
+ <issues id="41" component_uuid="FILE_3" project_uuid="PROJECT"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml
new file mode 100644
index 00000000000..e4a4ea22046
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/migrate.xml
@@ -0,0 +1,35 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" uuid="PROJECT" project_uuid="PROJECT" kee="org.struts:struts" enabled="[true]"/>
+ <issues id="1" component_uuid="PROJECT" project_uuid="PROJECT"/>
+
+ <!-- module -->
+ <projects id="10" uuid="MODULE" project_uuid="PROJECT" kee="org.struts:struts-core" enabled="[true]"/>
+
+ <!-- disabled sub module -> should be removed and its issues should be attached to the enabled one -->
+ <projects id="20" uuid="SUB_MODULE_1" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[false]"/>
+ <issues id="20" component_uuid="SUB_MODULE_1" project_uuid="PROJECT"/>
+ <issues id="21" component_uuid="SUB_MODULE_1" project_uuid="PROJECT"/>
+
+ <!-- enabled sub module -> issues from disabled should be attached to it -->
+ <projects id="21" uuid="SUB_MODULE_2" project_uuid="PROJECT" kee="org.struts:struts-data" enabled="[true]"/>
+ <issues id="22" component_uuid="SUB_MODULE_2" project_uuid="PROJECT"/>
+
+ <!-- disabled directories, only one should be kept -->
+ <projects id="30" uuid="DIRECTORY_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+ <projects id="31" uuid="DIRECTORY_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts"
+ enabled="[false]"/>
+
+ <!-- disabled files -> only one should be kept and issue from removed one should be attached to the remaining one -->
+ <projects id="40" uuid="FILE_1" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <projects id="41" uuid="FILE_2" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <projects id="42" uuid="FILE_3" project_uuid="PROJECT" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ enabled="[false]"/>
+ <issues id="40" component_uuid="FILE_1" project_uuid="PROJECT"/>
+ <issues id="41" component_uuid="FILE_3" project_uuid="PROJECT"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql
new file mode 100644
index 00000000000..19915dfd3b0
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest/schema.sql
@@ -0,0 +1,17 @@
+CREATE TABLE "PROJECTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "KEE" VARCHAR(400),
+ "UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50),
+ "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE
+);
+
+CREATE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE", "ENABLED");
+
+CREATE TABLE "ISSUES" (
+ "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "COMPONENT_UUID" VARCHAR(50),
+ "PROJECT_UUID" VARCHAR(50)
+);
+
+CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES" ("COMPONENT_UUID");
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml
new file mode 100644
index 00000000000..d9ebf91906c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries-result.xml
@@ -0,0 +1,24 @@
+<dataset>
+
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000"
+ version="[null]" path=""/>
+
+ <!-- Removed -->
+ <!--<snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"-->
+ <!--status="P" islast="[false]" purge_status="[null]"-->
+ <!--period1_mode="[null]" period1_param="[null]" period1_date="[null]"-->
+ <!--period2_mode="[null]" period2_param="[null]" period2_date="[null]"-->
+ <!--period3_mode="[null]" period3_param="[null]" period3_date="[null]"-->
+ <!--period4_mode="[null]" period4_param="[null]" period4_date="[null]"-->
+ <!--period5_mode="[null]" period5_param="[null]" period5_date="[null]"-->
+ <!--depth="[null]" scope="PRJ" qualifier="LIB" created_at="1228136280000" build_date="1228136280000"-->
+ <!--version="[null]" path=""/>-->
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml
new file mode 100644
index 00000000000..3cba1535e62
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/remove_libraries.xml
@@ -0,0 +1,24 @@
+<dataset>
+
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000"
+ version="[null]" path=""/>
+
+ <!-- Should be removed -->
+ <snapshots id="10" project_id="10" parent_snapshot_id="[null]" root_project_id="10" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="LIB" created_at="1228136280000" build_date="1228136280000"
+ version="[null]" path=""/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql
new file mode 100644
index 00000000000..832463b246c
--- /dev/null
+++ b/sonar-db/src/test/resources/org/sonar/db/version/v52/RemoveSnapshotLibrariesTest/schema.sql
@@ -0,0 +1,32 @@
+CREATE TABLE "SNAPSHOTS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "CREATED_AT" BIGINT,
+ "BUILD_DATE" BIGINT,
+ "PROJECT_ID" INTEGER NOT NULL,
+ "PARENT_SNAPSHOT_ID" INTEGER,
+ "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+ "PURGE_STATUS" INTEGER,
+ "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+ "SCOPE" VARCHAR(3),
+ "QUALIFIER" VARCHAR(10),
+ "ROOT_SNAPSHOT_ID" INTEGER,
+ "VERSION" VARCHAR(500),
+ "PATH" VARCHAR(500),
+ "DEPTH" INTEGER,
+ "ROOT_PROJECT_ID" INTEGER,
+ "PERIOD1_MODE" VARCHAR(100),
+ "PERIOD1_PARAM" VARCHAR(100),
+ "PERIOD1_DATE" BIGINT,
+ "PERIOD2_MODE" VARCHAR(100),
+ "PERIOD2_PARAM" VARCHAR(100),
+ "PERIOD2_DATE" BIGINT,
+ "PERIOD3_MODE" VARCHAR(100),
+ "PERIOD3_PARAM" VARCHAR(100),
+ "PERIOD3_DATE" BIGINT,
+ "PERIOD4_MODE" VARCHAR(100),
+ "PERIOD4_PARAM" VARCHAR(100),
+ "PERIOD4_DATE" BIGINT,
+ "PERIOD5_MODE" VARCHAR(100),
+ "PERIOD5_PARAM" VARCHAR(100),
+ "PERIOD5_DATE" BIGINT
+);