/* * SonarQube * Copyright (C) 2009-2023 SonarSource SA * mailto:info AT sonarsource DOT com * * This program 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. * * This program 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.component; import com.google.common.collect.Sets; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.metric.MetricDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.protobuf.DbProjectBranches; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang.StringUtils.repeat; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.db.component.BranchType.PULL_REQUEST; @RunWith(DataProviderRunner.class) public class BranchDaoIT { private static final long NOW = 1_000L; private static final String SELECT_FROM = """ select project_uuid as "projectUuid", uuid as "uuid", branch_type as "branchType", kee as "kee", merge_branch_uuid as "mergeBranchUuid", pull_request_binary as "pullRequestBinary", created_at as "createdAt", updated_at as "updatedAt", is_main as "isMain" from project_branches"""; private System2 system2 = new TestSystem2().setNow(NOW); @Rule public DbTester db = DbTester.create(system2); private DbSession dbSession = db.getSession(); private BranchDao underTest = new BranchDao(system2); @Test public void insert_branch_with_only_nonnull_fields() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U2"); dto.setBranchType(BranchType.BRANCH); dto.setIsMain(true); dto.setKey("feature/foo"); underTest.insert(dbSession, dto); Map map = db.selectFirst(dbSession, SELECT_FROM + " where uuid='" + dto.getUuid() + "'"); assertThat(map).contains( entry("projectUuid", "U1"), entry("uuid", "U2"), entry("branchType", "BRANCH"), entry("kee", "feature/foo"), entry("mergeBranchUuid", null), entry("pullRequestBinary", null), entry("createdAt", 1_000L), entry("updatedAt", 1_000L)); assertThat(map.get("isMain")).isIn(true, 1L); // Oracle returns 1L instead of true } @Test public void update_main_branch_name() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U1"); dto.setIsMain(true); dto.setBranchType(BranchType.BRANCH); dto.setKey("feature"); underTest.insert(dbSession, dto); BranchDto dto2 = new BranchDto(); dto2.setProjectUuid("U2"); dto2.setUuid("U2"); dto2.setIsMain(true); dto2.setBranchType(BranchType.BRANCH); dto2.setKey("branch"); underTest.insert(dbSession, dto2); underTest.updateBranchName(dbSession, "U1", "master"); BranchDto loaded = underTest.selectByBranchKey(dbSession, "U1", "master").get(); assertThat(loaded.getMergeBranchUuid()).isNull(); assertThat(loaded.getProjectUuid()).isEqualTo("U1"); assertThat(loaded.getBranchType()).isEqualTo(BranchType.BRANCH); assertThat(loaded.isMain()).isTrue(); } @Test public void selectBranchMeasuresForTelemetry() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U1"); dto.setBranchType(BranchType.BRANCH); dto.setKey("feature"); dto.setIsMain(true); dto.setExcludeFromPurge(false); underTest.insert(dbSession, dto); MetricDto qg = db.measures().insertMetric(m -> m.setKey(ALERT_STATUS_KEY)); SnapshotDto analysis = db.components().insertSnapshot(dto); db.measures().insertMeasure(dto, analysis, qg, pm -> pm.setData("OK")); var branchMeasures = underTest.selectBranchMeasuresWithCaycMetric(dbSession); assertThat(branchMeasures) .hasSize(1) .extracting(BranchMeasuresDto::getBranchUuid, BranchMeasuresDto::getBranchKey, BranchMeasuresDto::getProjectUuid, BranchMeasuresDto::getAnalysisCount, BranchMeasuresDto::getGreenQualityGateCount, BranchMeasuresDto::getExcludeFromPurge) .containsExactly(tuple("U1", "feature", "U1", 1, 1, false)); } @Test public void updateExcludeFromPurge() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U1"); dto.setBranchType(BranchType.BRANCH); dto.setKey("feature"); dto.setIsMain(true); dto.setExcludeFromPurge(false); underTest.insert(dbSession, dto); underTest.updateExcludeFromPurge(dbSession, "U1", true); BranchDto loaded = underTest.selectByBranchKey(dbSession, "U1", "feature").get(); assertThat(loaded.isExcludeFromPurge()).isTrue(); } @DataProvider public static Object[][] nullOrEmpty() { return new Object[][] { {null}, {""} }; } @DataProvider public static Object[][] oldAndNewValuesCombinations() { String value1 = randomAlphabetic(10); String value2 = randomAlphabetic(20); return new Object[][] { {null, value1}, {"", value1}, {value1, null}, {value1, ""}, {value1, value2}, {null, null}, {"", null}, {value1, value1} }; } @Test public void insert_branch_with_all_fields_and_max_length_values() { BranchDto dto = new BranchDto(); dto.setProjectUuid(repeat("a", 50)); dto.setUuid(repeat("b", 50)); dto.setIsMain(false); dto.setBranchType(BranchType.BRANCH); dto.setKey(repeat("c", 255)); dto.setMergeBranchUuid(repeat("d", 50)); underTest.insert(dbSession, dto); Map map = db.selectFirst(dbSession, SELECT_FROM + " where uuid='" + dto.getUuid() + "'"); assertThat((String) map.get("projectUuid")).contains("a").isEqualTo(dto.getProjectUuid()); assertThat((String) map.get("uuid")).contains("b").isEqualTo(dto.getUuid()); assertThat((String) map.get("kee")).contains("c").isEqualTo(dto.getKey()); assertThat((String) map.get("mergeBranchUuid")).contains("d").isEqualTo(dto.getMergeBranchUuid()); } @Test public void insert_pull_request_branch_with_only_non_null_fields() { String projectUuid = "U1"; String uuid = "U2"; BranchType branchType = BranchType.PULL_REQUEST; String kee = "123"; BranchDto dto = new BranchDto(); dto.setProjectUuid(projectUuid); dto.setUuid(uuid); dto.setIsMain(false); dto.setBranchType(branchType); dto.setKey(kee); underTest.insert(dbSession, dto); BranchDto loaded = underTest.selectByUuid(dbSession, dto.getUuid()).get(); assertThat(loaded.getProjectUuid()).isEqualTo(projectUuid); assertThat(loaded.getUuid()).isEqualTo(uuid); assertThat(loaded.isMain()).isFalse(); assertThat(loaded.getBranchType()).isEqualTo(branchType); assertThat(loaded.getKey()).isEqualTo(kee); assertThat(loaded.getMergeBranchUuid()).isNull(); assertThat(loaded.getPullRequestData()).isNull(); } @Test public void insert_pull_request_branch_with_all_fields() { String projectUuid = "U1"; String uuid = "U2"; BranchType branchType = BranchType.PULL_REQUEST; String kee = "123"; String branch = "feature/pr1"; String title = "Dummy Feature Title"; String url = "http://example.com/pullRequests/pr1"; String tokenAttributeName = "token"; String tokenAttributeValue = "dummy token"; DbProjectBranches.PullRequestData pullRequestData = DbProjectBranches.PullRequestData.newBuilder() .setBranch(branch) .setTitle(title) .setUrl(url) .putAttributes(tokenAttributeName, tokenAttributeValue) .build(); BranchDto dto = new BranchDto(); dto.setProjectUuid(projectUuid); dto.setUuid(uuid); dto.setIsMain(false); dto.setBranchType(branchType); dto.setKey(kee); dto.setPullRequestData(pullRequestData); underTest.insert(dbSession, dto); BranchDto loaded = underTest.selectByUuid(dbSession, dto.getUuid()).get(); assertThat(loaded.getProjectUuid()).isEqualTo(projectUuid); assertThat(loaded.getUuid()).isEqualTo(uuid); assertThat(loaded.getBranchType()).isEqualTo(branchType); assertThat(loaded.getKey()).isEqualTo(kee); assertThat(loaded.getMergeBranchUuid()).isNull(); DbProjectBranches.PullRequestData loadedPullRequestData = loaded.getPullRequestData(); assertThat(loadedPullRequestData).isNotNull(); assertThat(loadedPullRequestData.getBranch()).isEqualTo(branch); assertThat(loadedPullRequestData.getTitle()).isEqualTo(title); assertThat(loadedPullRequestData.getUrl()).isEqualTo(url); assertThat(loadedPullRequestData.getAttributesMap()).containsEntry(tokenAttributeName, tokenAttributeValue); } @Test public void upsert_branch() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U2"); dto.setIsMain(false); dto.setBranchType(BranchType.BRANCH); dto.setKey("foo"); underTest.insert(dbSession, dto); // the fields that can be updated dto.setMergeBranchUuid("U3"); // the fields that can't be updated. New values are ignored. dto.setProjectUuid("ignored"); dto.setBranchType(BranchType.BRANCH); underTest.upsert(dbSession, dto); BranchDto loaded = underTest.selectByBranchKey(dbSession, "U1", "foo").get(); assertThat(loaded.getMergeBranchUuid()).isEqualTo("U3"); assertThat(loaded.getProjectUuid()).isEqualTo("U1"); assertThat(loaded.getBranchType()).isEqualTo(BranchType.BRANCH); } @Test public void upsert_pull_request() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U2"); dto.setBranchType(BranchType.PULL_REQUEST); dto.setKey("foo"); dto.setIsMain(false); underTest.insert(dbSession, dto); // the fields that can be updated dto.setMergeBranchUuid("U3"); String branch = "feature/pr1"; String title = "Dummy Feature Title"; String url = "http://example.com/pullRequests/pr1"; String tokenAttributeName = "token"; String tokenAttributeValue = "dummy token"; DbProjectBranches.PullRequestData pullRequestData = DbProjectBranches.PullRequestData.newBuilder() .setBranch(branch) .setTitle(title) .setUrl(url) .putAttributes(tokenAttributeName, tokenAttributeValue) .build(); dto.setPullRequestData(pullRequestData); // the fields that can't be updated. New values are ignored. dto.setProjectUuid("ignored"); dto.setBranchType(BranchType.BRANCH); underTest.upsert(dbSession, dto); BranchDto loaded = underTest.selectByPullRequestKey(dbSession, "U1", "foo").get(); assertThat(loaded.getMergeBranchUuid()).isEqualTo("U3"); assertThat(loaded.getProjectUuid()).isEqualTo("U1"); assertThat(loaded.getBranchType()).isEqualTo(BranchType.PULL_REQUEST); DbProjectBranches.PullRequestData loadedPullRequestData = loaded.getPullRequestData(); assertThat(loadedPullRequestData).isNotNull(); assertThat(loadedPullRequestData.getBranch()).isEqualTo(branch); assertThat(loadedPullRequestData.getTitle()).isEqualTo(title); assertThat(loadedPullRequestData.getUrl()).isEqualTo(url); assertThat(loadedPullRequestData.getAttributesMap()).containsEntry(tokenAttributeName, tokenAttributeValue); } @Test public void update_pull_request_data() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U2"); dto.setIsMain(false); dto.setBranchType(BranchType.PULL_REQUEST); dto.setKey("foo"); // the fields that can be updated String mergeBranchUuid = "U3"; dto.setMergeBranchUuid(mergeBranchUuid + "-dummy-suffix"); String branch = "feature/pr1"; String title = "Dummy Feature Title"; String url = "http://example.com/pullRequests/pr1"; String tokenAttributeName = "token"; String tokenAttributeValue = "dummy token"; DbProjectBranches.PullRequestData pullRequestData = DbProjectBranches.PullRequestData.newBuilder() .setBranch(branch + "-dummy-suffix") .setTitle(title + "-dummy-suffix") .setUrl(url + "-dummy-suffix") .putAttributes(tokenAttributeName, tokenAttributeValue + "-dummy-suffix") .build(); dto.setPullRequestData(pullRequestData); underTest.insert(dbSession, dto); // modify pull request data dto.setMergeBranchUuid(mergeBranchUuid); pullRequestData = DbProjectBranches.PullRequestData.newBuilder() .setBranch(branch) .setTitle(title) .setUrl(url) .putAttributes(tokenAttributeName, tokenAttributeValue) .build(); dto.setPullRequestData(pullRequestData); underTest.upsert(dbSession, dto); BranchDto loaded = underTest.selectByPullRequestKey(dbSession, "U1", "foo").get(); assertThat(loaded.getMergeBranchUuid()).isEqualTo(mergeBranchUuid); assertThat(loaded.getProjectUuid()).isEqualTo("U1"); assertThat(loaded.getBranchType()).isEqualTo(BranchType.PULL_REQUEST); DbProjectBranches.PullRequestData loadedPullRequestData = loaded.getPullRequestData(); assertThat(loadedPullRequestData).isNotNull(); assertThat(loadedPullRequestData.getBranch()).isEqualTo(branch); assertThat(loadedPullRequestData.getTitle()).isEqualTo(title); assertThat(loadedPullRequestData.getUrl()).isEqualTo(url); assertThat(loadedPullRequestData.getAttributesMap()).containsEntry(tokenAttributeName, tokenAttributeValue); } @Test public void selectByBranchKey() { BranchDto mainBranch = new BranchDto(); mainBranch.setProjectUuid("U1"); mainBranch.setUuid("U1"); mainBranch.setIsMain(true); mainBranch.setBranchType(BranchType.BRANCH); mainBranch.setKey("master"); underTest.insert(dbSession, mainBranch); BranchDto featureBranch = new BranchDto(); featureBranch.setProjectUuid("U1"); featureBranch.setUuid("U2"); featureBranch.setIsMain(false); featureBranch.setBranchType(BranchType.BRANCH); featureBranch.setKey("feature/foo"); featureBranch.setMergeBranchUuid("U3"); underTest.insert(dbSession, featureBranch); // select the feature branch BranchDto loaded = underTest.selectByBranchKey(dbSession, "U1", "feature/foo").get(); assertThat(loaded.getUuid()).isEqualTo(featureBranch.getUuid()); assertThat(loaded.getKey()).isEqualTo(featureBranch.getKey()); assertThat(loaded.isMain()).isFalse(); assertThat(loaded.getProjectUuid()).isEqualTo(featureBranch.getProjectUuid()); assertThat(loaded.getBranchType()).isEqualTo(featureBranch.getBranchType()); assertThat(loaded.getMergeBranchUuid()).isEqualTo(featureBranch.getMergeBranchUuid()); // select a branch on another project with same branch name assertThat(underTest.selectByBranchKey(dbSession, "U3", "feature/foo")).isEmpty(); } @Test public void selectByBranchKeys() { ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project3 = db.components().insertPrivateProject().getProjectDto(); BranchDto branch1 = db.components().insertProjectBranch(project1, b -> b.setKey("branch1")); BranchDto branch2 = db.components().insertProjectBranch(project2, b -> b.setKey("branch2")); BranchDto branch3 = db.components().insertProjectBranch(project3, b -> b.setKey("branch3")); Map branchKeysByProjectUuid = new HashMap<>(); branchKeysByProjectUuid.put(project1.getUuid(), "branch1"); branchKeysByProjectUuid.put(project2.getUuid(), "branch2"); branchKeysByProjectUuid.put(project3.getUuid(), "nonexisting"); List branchDtos = underTest.selectByBranchKeys(dbSession, branchKeysByProjectUuid); assertThat(branchDtos).hasSize(2); assertThat(branchDtos).extracting(BranchDto::getUuid).containsExactlyInAnyOrder(branch1.getUuid(), branch2.getUuid()); } @Test public void selectByComponent() { BranchDto mainBranch = new BranchDto(); mainBranch.setProjectUuid("U1"); mainBranch.setUuid("U1"); mainBranch.setIsMain(true); mainBranch.setBranchType(BranchType.BRANCH); mainBranch.setKey("master"); underTest.insert(dbSession, mainBranch); BranchDto featureBranch = new BranchDto(); featureBranch.setProjectUuid("U1"); featureBranch.setUuid("U2"); featureBranch.setIsMain(false); featureBranch.setBranchType(BranchType.BRANCH); featureBranch.setKey("feature/foo"); featureBranch.setMergeBranchUuid("U3"); underTest.insert(dbSession, featureBranch); ComponentDto component = new ComponentDto().setBranchUuid(mainBranch.getUuid()); // select the component Collection branches = underTest.selectByComponent(dbSession, component); assertThat(branches).hasSize(2); assertThat(branches).extracting(BranchDto::getUuid, BranchDto::getKey, BranchDto::isMain, BranchDto::getProjectUuid, BranchDto::getBranchType, BranchDto::getMergeBranchUuid) .containsOnly(tuple(mainBranch.getUuid(), mainBranch.getKey(), mainBranch.isMain(), mainBranch.getProjectUuid(), mainBranch.getBranchType(), mainBranch.getMergeBranchUuid()), tuple(featureBranch.getUuid(), featureBranch.getKey(), featureBranch.isMain(), featureBranch.getProjectUuid(), featureBranch.getBranchType(), featureBranch.getMergeBranchUuid())); } @Test public void selectByPullRequestKey() { BranchDto mainBranch = new BranchDto(); mainBranch.setProjectUuid("U1"); mainBranch.setUuid("U1"); mainBranch.setBranchType(BranchType.BRANCH); mainBranch.setKey("master"); mainBranch.setIsMain(true); underTest.insert(dbSession, mainBranch); String pullRequestId = "123"; BranchDto pullRequest = new BranchDto(); pullRequest.setIsMain(false); pullRequest.setProjectUuid("U1"); pullRequest.setUuid("U2"); pullRequest.setBranchType(BranchType.PULL_REQUEST); pullRequest.setKey(pullRequestId); pullRequest.setMergeBranchUuid("U3"); underTest.insert(dbSession, pullRequest); // select the feature branch BranchDto loaded = underTest.selectByPullRequestKey(dbSession, "U1", pullRequestId).get(); assertThat(loaded.getUuid()).isEqualTo(pullRequest.getUuid()); assertThat(loaded.getKey()).isEqualTo(pullRequest.getKey()); assertThat(loaded.getProjectUuid()).isEqualTo(pullRequest.getProjectUuid()); assertThat(loaded.getBranchType()).isEqualTo(pullRequest.getBranchType()); assertThat(loaded.getMergeBranchUuid()).isEqualTo(pullRequest.getMergeBranchUuid()); // select a branch on another project with same branch name assertThat(underTest.selectByPullRequestKey(dbSession, "U3", pullRequestId)).isEmpty(); } @Test public void selectByKeys() { BranchDto mainBranch = new BranchDto() .setProjectUuid("U1") .setUuid("U1") .setIsMain(true) .setBranchType(BranchType.BRANCH) .setKey("master"); underTest.insert(dbSession, mainBranch); BranchDto featureBranch = new BranchDto() .setProjectUuid("U1") .setUuid("U2") .setIsMain(false) .setBranchType(BranchType.BRANCH) .setKey("feature1"); underTest.insert(dbSession, featureBranch); String pullRequestId = "123"; BranchDto pullRequest = new BranchDto() .setProjectUuid("U1") .setUuid("U3") .setIsMain(false) .setBranchType(BranchType.PULL_REQUEST) .setKey(pullRequestId) .setMergeBranchUuid("U4"); underTest.insert(dbSession, pullRequest); assertThat(underTest.selectByKeys(dbSession, "U1", Collections.emptySet())) .isEmpty(); List loaded = underTest.selectByKeys(dbSession, "U1", Set.of(mainBranch.getKey(), featureBranch.getKey())); assertThat(loaded) .extracting(BranchDto::getUuid) .containsExactlyInAnyOrder(mainBranch.getUuid(), featureBranch.getUuid()); } @Test public void selectByUuids() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto branch1 = db.components().insertProjectBranch(project); ComponentDto branch2 = db.components().insertProjectBranch(project); ComponentDto branch3 = db.components().insertProjectBranch(project); assertThat(underTest.selectByUuids(db.getSession(), asList(branch1.uuid(), branch2.uuid(), branch3.uuid()))) .extracting(BranchDto::getUuid) .containsExactlyInAnyOrder(branch1.uuid(), branch2.uuid(), branch3.uuid()); assertThat(underTest.selectByUuids(db.getSession(), singletonList(branch1.uuid()))) .extracting(BranchDto::getUuid) .containsExactlyInAnyOrder(branch1.uuid()); assertThat(underTest.selectByUuids(db.getSession(), singletonList("unknown"))).isEmpty(); } @Test public void selectByProjectUuid() { ProjectData projectData1 = db.components().insertPrivateProject(); ComponentDto mainBranch1 = projectData1.getMainBranchComponent(); ProjectData projectData2 = db.components().insertPrivateProject(); ComponentDto mainBranch2 = projectData2.getMainBranchComponent(); ComponentDto branch1 = db.components().insertProjectBranch(mainBranch1); ComponentDto branch2 = db.components().insertProjectBranch(mainBranch1); ComponentDto branch3 = db.components().insertProjectBranch(mainBranch2); ComponentDto branch4 = db.components().insertProjectBranch(mainBranch2); assertThat(underTest.selectByProject(dbSession, new ProjectDto().setUuid(projectData1.projectUuid()))) .extracting(BranchDto::getUuid) .containsExactlyInAnyOrder(mainBranch1.uuid(), branch1.uuid(), branch2.uuid()); assertThat(underTest.selectByProject(dbSession, new ProjectDto().setUuid(projectData2.projectUuid()))) .extracting(BranchDto::getUuid) .containsExactlyInAnyOrder(mainBranch2.uuid(), branch3.uuid(), branch4.uuid()); } @Test public void selectByUuid() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto branch1 = db.components().insertProjectBranch(project); ComponentDto branch2 = db.components().insertProjectBranch(project); assertThat(underTest.selectByUuid(db.getSession(), branch1.uuid()).get()) .extracting(BranchDto::getUuid) .isEqualTo(branch1.uuid()); assertThat(underTest.selectByUuid(db.getSession(), project.uuid())).isPresent(); assertThat(underTest.selectByUuid(db.getSession(), "unknown")).isNotPresent(); } @Test public void countPrAndBranchByProjectUuid() { ProjectData projectData1 = db.components().insertPrivateProject(); ComponentDto project1 = projectData1.getMainBranchComponent(); db.components().insertProjectBranch(project1, b -> b.setBranchType(BRANCH).setKey("p1-branch-1")); db.components().insertProjectBranch(project1, b -> b.setBranchType(BRANCH).setKey("p1-branch-2")); db.components().insertProjectBranch(project1, b -> b.setBranchType(PULL_REQUEST).setKey("p1-pr-1")); db.components().insertProjectBranch(project1, b -> b.setBranchType(PULL_REQUEST).setKey("p1-pr-2")); db.components().insertProjectBranch(project1, b -> b.setBranchType(PULL_REQUEST).setKey("p1-pr-3")); ProjectData projectData2 = db.components().insertPrivateProject(); ComponentDto project2 = projectData2.getMainBranchComponent(); db.components().insertProjectBranch(project2, b -> b.setBranchType(PULL_REQUEST).setKey("p2-pr-1")); ProjectData projectData3 = db.components().insertPrivateProject(); ComponentDto project3 = projectData3.getMainBranchComponent(); db.components().insertProjectBranch(project3, b -> b.setBranchType(BRANCH).setKey("p3-branch-1")); MetricDto unanalyzedC = db.measures().insertMetric(m -> m.setKey("unanalyzed_c")); MetricDto unanalyzedCpp = db.measures().insertMetric(m -> m.setKey("unanalyzed_cpp")); db.measures().insertLiveMeasure(project1, unanalyzedC); db.measures().insertLiveMeasure(project1, unanalyzedCpp); db.measures().insertLiveMeasure(project2, unanalyzedCpp); db.measures().insertLiveMeasure(project3, unanalyzedC); assertThat(underTest.countPrBranchAnalyzedLanguageByProjectUuid(db.getSession())) .extracting(PrBranchAnalyzedLanguageCountByProjectDto::getProjectUuid, PrBranchAnalyzedLanguageCountByProjectDto::getBranch, PrBranchAnalyzedLanguageCountByProjectDto::getPullRequest) .containsExactlyInAnyOrder( tuple(projectData1.projectUuid(), 3L, 3L), tuple(projectData2.projectUuid(), 1L, 1L), tuple(projectData3.projectUuid(), 2L, 0L) ); } @Test public void selectProjectUuidsWithIssuesNeedSync() { ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto project3 = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto project4 = db.components().insertPrivateProject().getMainBranchComponent(); ProjectDto project1Dto = db.components().getProjectDtoByMainBranch(project1); ProjectDto project2Dto = db.components().getProjectDtoByMainBranch(project2); ProjectDto project3Dto = db.components().getProjectDtoByMainBranch(project3); ProjectDto project4Dto = db.components().getProjectDtoByMainBranch(project4); BranchDto branch1 = db.components().insertProjectBranch(project1Dto, branchDto -> branchDto.setNeedIssueSync(true)); BranchDto branch2 = db.components().insertProjectBranch(project1Dto, branchDto -> branchDto.setNeedIssueSync(false)); BranchDto branch3 = db.components().insertProjectBranch(project2Dto); assertThat(underTest.selectProjectUuidsWithIssuesNeedSync(db.getSession(), Sets.newHashSet(project1Dto.getUuid(), project2Dto.getUuid(), project3Dto.getUuid(), project4Dto.getUuid()))) .containsOnly(project1Dto.getUuid()); } @Test public void hasAnyBranchWhereNeedIssueSync() { assertThat(underTest.hasAnyBranchWhereNeedIssueSync(dbSession, true)).isFalse(); assertThat(underTest.hasAnyBranchWhereNeedIssueSync(dbSession, false)).isFalse(); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setNeedIssueSync(false)); assertThat(underTest.hasAnyBranchWhereNeedIssueSync(dbSession, true)).isFalse(); assertThat(underTest.hasAnyBranchWhereNeedIssueSync(dbSession, false)).isTrue(); project = db.components().insertPrivateProject().getMainBranchComponent(); branch = db.components().insertProjectBranch(project, b -> b.setNeedIssueSync(true)); assertThat(underTest.hasAnyBranchWhereNeedIssueSync(dbSession, true)).isTrue(); } @Test public void countByTypeAndCreationDate() { assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.BRANCH, 0L)).isZero(); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto branch1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); ComponentDto branch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST)); assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.BRANCH, 0L)).isEqualTo(3); assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.BRANCH, NOW)).isEqualTo(3); assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.BRANCH, NOW + 100)).isZero(); assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.PULL_REQUEST, 0L)).isOne(); assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.PULL_REQUEST, NOW)).isOne(); assertThat(underTest.countByTypeAndCreationDate(dbSession, BranchType.PULL_REQUEST, NOW + 100)).isZero(); } @Test public void countByNeedIssueSync() { assertThat(underTest.countByNeedIssueSync(dbSession, true)).isZero(); assertThat(underTest.countByNeedIssueSync(dbSession, false)).isZero(); // master branch with flag set to false ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); // branches & PRs db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); assertThat(underTest.countByNeedIssueSync(dbSession, true)).isEqualTo(4); assertThat(underTest.countByNeedIssueSync(dbSession, false)).isEqualTo(4); } @Test public void countAll() { assertThat(underTest.countAll(dbSession)).isZero(); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false)); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); assertThat(underTest.countAll(dbSession)).isEqualTo(8); } @Test public void selectBranchNeedingIssueSync() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); String uuid = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)).uuid(); db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); assertThat(underTest.selectBranchNeedingIssueSync(dbSession)) .extracting(BranchDto::getUuid) .containsExactly(uuid); } @Test public void selectBranchNeedingIssueSyncForProject() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); String uuid = db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)).uuid(); db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); assertThat(underTest.selectBranchNeedingIssueSyncForProject(dbSession, projectData.projectUuid())) .extracting(BranchDto::getUuid) .containsExactly(uuid); } @Test public void updateAllNeedIssueSync() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); String uuid1 = db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)).uuid(); String uuid2 = db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)).uuid(); underTest.updateAllNeedIssueSync(dbSession); Optional project1 = underTest.selectByUuid(dbSession, uuid1); assertThat(project1).isPresent(); assertThat(project1.get().isNeedIssueSync()).isTrue(); Optional project2 = underTest.selectByUuid(dbSession, uuid2); assertThat(project2).isPresent(); assertThat(project2.get().isNeedIssueSync()).isTrue(); } @Test public void updateAllNeedIssueSyncForProject() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); String uuid1 = db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)).uuid(); String uuid2 = db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)).uuid(); underTest.updateAllNeedIssueSyncForProject(dbSession, projectData.projectUuid()); Optional project1 = underTest.selectByUuid(dbSession, uuid1); assertThat(project1).isPresent(); assertThat(project1.get().isNeedIssueSync()).isTrue(); Optional project2 = underTest.selectByUuid(dbSession, uuid2); assertThat(project2).isPresent(); assertThat(project2.get().isNeedIssueSync()).isTrue(); } @Test public void updateNeedIssueSync() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); String uuid1 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)).uuid(); String uuid2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)).uuid(); underTest.updateNeedIssueSync(dbSession, uuid1, true); underTest.updateNeedIssueSync(dbSession, uuid2, false); Optional project1 = underTest.selectByUuid(dbSession, uuid1); assertThat(project1).isPresent(); assertThat(project1.get().isNeedIssueSync()).isTrue(); Optional project2 = underTest.selectByUuid(dbSession, uuid2); assertThat(project2).isPresent(); assertThat(project2.get().isNeedIssueSync()).isFalse(); } @Test public void doAnyOfComponentsNeedIssueSync() { assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, emptyList())).isFalse(); ProjectData projectData1 = db.components().insertPrivateProject(); ComponentDto project1 = projectData1.getMainBranchComponent(); ProjectData projectData2 = db.components().insertPrivateProject(); ComponentDto project2 = projectData2.getMainBranchComponent(); db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); BranchDto projectBranch1 = db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); BranchDto projectBranch2 = db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); BranchDto pullRequest1 = db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); BranchDto pullRequest2 = db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false)); db.components().insertProjectBranch(projectData1.getProjectDto(), b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(projectData1.projectKey()))).isTrue(); assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(projectData2.projectKey()))).isFalse(); } @Test public void doAnyOfComponentsNeedIssueSync_test_more_than_1000() { List componentKeys = IntStream.range(0, 1100).mapToObj(value -> db.components().insertPrivateProject().getMainBranchComponent()) .map(ComponentDto::getKey) .collect(Collectors.toCollection(ArrayList::new)); assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, componentKeys)).isFalse(); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ProjectDto projectDto = db.components().getProjectDtoByMainBranch(project); db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); componentKeys.add(project.getKey()); assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, componentKeys)).isTrue(); } @DataProvider public static Object[][] booleanValues() { return new Object[][] { {true}, {false} }; } @Test @UseDataProvider("booleanValues") public void isBranchNeedIssueSync_shouldReturnCorrectValue(boolean needIssueSync) { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); String branchUuid = db.components().insertProjectBranch(project, branch -> branch.setBranchType(BranchType.BRANCH).setNeedIssueSync(needIssueSync)).uuid(); assertThat(underTest.isBranchNeedIssueSync(dbSession, branchUuid)).isEqualTo(needIssueSync); } @Test public void isBranchNeedIssueSync_whenNoBranch_shouldReturnFalse() { assertThat(underTest.isBranchNeedIssueSync(dbSession, "unknown")).isFalse(); } @Test public void selectMainBranchByProjectUuid_whenMainBranch_shouldReturnMainBranch() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U1"); dto.setIsMain(true); dto.setBranchType(BranchType.BRANCH); dto.setKey("feature"); underTest.insert(dbSession, dto); assertThat(underTest.selectMainBranchByProjectUuid(dbSession, "U1")).get() .extracting(e -> e.getUuid()).isEqualTo("U1"); } @Test public void selectMainBranchByProjectUuid_whenNonMainBranch_shouldReturnEmpty() { BranchDto dto = new BranchDto(); dto.setProjectUuid("U1"); dto.setUuid("U2"); dto.setIsMain(false); dto.setBranchType(BranchType.BRANCH); dto.setKey("feature"); underTest.insert(dbSession, dto); assertThat(underTest.selectMainBranchByProjectUuid(dbSession, "U1")).isEmpty(); } @Test public void selectMainBranchesByProjectUuids_whenNoUuidsPassed_shouldReturnEmpty() { insertBranchesForProjectUuids(true, "1"); List branchDtos = underTest.selectMainBranchesByProjectUuids(dbSession, Set.of()); assertThat(branchDtos).isEmpty(); } @Test public void selectMainBranchesByProjectUuids_whenOneUuidPassedAndTwoBranchesInDatabase_shouldReturnOneBranch() { insertBranchesForProjectUuids(true, "1", "2"); List branchDtos = underTest.selectMainBranchesByProjectUuids(dbSession, Set.of("1")); assertThat(branchDtos).hasSize(1); assertThat(branchDtos).extracting(BranchDto::getProjectUuid).allMatch(s -> s.equals("1")); } @Test public void selectMainBranchesByProjectUuids_whenTenUuidsPassedAndTenBranchesInDatabase_shouldReturnAllBranches() { String[] projectUuids = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; insertBranchesForProjectUuids(true, projectUuids); insertBranchesForProjectUuids(false, projectUuids); List branchDtos = underTest.selectMainBranchesByProjectUuids(dbSession, Set.of(projectUuids)); assertThat(branchDtos).hasSize(10); assertThat(branchDtos).extracting(BranchDto::isMain).allMatch(b -> true); } private void insertBranchesForProjectUuids(boolean mainBranch, String... uuids) { for (String uuid : uuids) { BranchDto dto = new BranchDto(); dto.setProjectUuid(uuid); dto.setUuid(uuid + "-uuid" + mainBranch); dto.setIsMain(mainBranch); dto.setBranchType(BranchType.BRANCH); dto.setKey("feature-" + uuid + mainBranch); underTest.insert(dbSession, dto); } } }