Browse Source

SONAR-21643 Make rule compatible with JUnit5 (#10700)

tags/10.5.0.89998
Dejan Milisavljevic 2 months ago
parent
commit
990606438b
48 changed files with 654 additions and 817 deletions
  1. 8
    0
      server/sonar-auth-ldap/build.gradle
  2. 15
    14
      server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorIT.java
  3. 15
    2
      server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/server/LdapServer.java
  4. 2
    0
      server/sonar-ce-task-projectanalysis/build.gradle
  5. 21
    21
      server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistDuplicationDataStepIT.java
  6. 7
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java
  7. 47
    46
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentTreeBuilderTest.java
  8. 14
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/duplication/DuplicationRepositoryRule.java
  9. 14
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/filemove/MutableMovedFilesRepositoryRule.java
  10. 18
    19
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java
  11. 7
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/FillComponentIssuesVisitorRule.java
  12. 25
    25
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueAssignerTest.java
  13. 20
    21
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssuesRepositoryVisitorTest.java
  14. 7
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryRule.java
  15. 44
    46
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactoryTest.java
  16. 9
    9
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureComputersHolderRule.java
  17. 16
    16
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/ViewsMeasureComputersVisitorTest.java
  18. 9
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/period/PeriodHolderRule.java
  19. 8
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitygate/MutableQualityGateHolderRule.java
  20. 8
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitygate/MutableQualityGateStatusHolderRule.java
  21. 8
    6
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitygate/QualityGateHolderRule.java
  22. 37
    36
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java
  23. 8
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualityprofile/ActiveRulesHolderRule.java
  24. 8
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepositoryRule.java
  25. 18
    22
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceHashRepositoryImplTest.java
  26. 14
    13
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImplTest.java
  27. 8
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesRepositoryRule.java
  28. 10
    10
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadQualityGateStepTest.java
  29. 11
    11
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadQualityProfilesStepTest.java
  30. 32
    30
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/QualityGateMeasuresStepTest.java
  31. 8
    1
      server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java
  32. 9
    1
      server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java
  33. 8
    1
      server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/component/TreeRootHolderRule.java
  34. 8
    1
      server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryRule.java
  35. 8
    1
      server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/metric/MetricRepositoryRule.java
  36. 14
    21
      server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/step/BaseStepJUnit5Test.java
  37. 69
    68
      server/sonar-ce/src/it/java/org/sonar/ce/taskprocessor/CeWorkerImplIT.java
  38. 1
    1
      server/sonar-ce/src/test/java/org/sonar/ce/configuration/CeConfigurationRule.java
  39. 1
    1
      server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeProcessingSchedulerImplTest.java
  40. 9
    1
      server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeTaskProcessorRepositoryRule.java
  41. 0
    1
      server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeWorkerControllerImplTest.java
  42. 9
    0
      server/sonar-process/build.gradle
  43. 16
    2
      server/sonar-process/src/test/java/org/sonar/process/LoggingRule.java
  44. 10
    9
      server/sonar-process/src/test/java/org/sonar/process/cluster/health/HealthStateRefresherTest.java
  45. 9
    1
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryRule.java
  46. 7
    7
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileLoaderTest.java
  47. 0
    1
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java
  48. 0
    341
      sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java

+ 8
- 0
server/sonar-auth-ldap/build.gradle View File

@@ -17,7 +17,15 @@ dependencies {
testImplementation 'com.tngtech.java:junit-dataprovider'
testImplementation 'junit:junit'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.mockito:mockito-core'
testImplementation project(":sonar-testing-ldap")

testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
}

test {
// Enabling the JUnit Platform (see https://github.com/junit-team/junit5-samples/tree/master/junit5-migration-gradle)
useJUnitPlatform()
}

+ 15
- 14
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/DefaultLdapAuthenticatorIT.java View File

@@ -19,8 +19,8 @@
*/
package org.sonar.auth.ldap;

import org.junit.ClassRule;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.server.http.HttpRequest;
import org.sonar.auth.ldap.server.LdapServer;
@@ -28,23 +28,24 @@ import org.sonar.auth.ldap.server.LdapServer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class DefaultLdapAuthenticatorIT {
class DefaultLdapAuthenticatorIT {

/**
* A reference to the original ldif file
*/
public static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
private static final String USERS_EXAMPLE_ORG_LDIF = "/users.example.org.ldif";
/**
* A reference to an additional ldif file.
*/
public static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
@ClassRule
public static LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
@ClassRule
public static LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport,dc=com");
private static final String USERS_INFOSUPPORT_COM_LDIF = "/users.infosupport.com.ldif";
@RegisterExtension
private static final LdapServer exampleServer = new LdapServer(USERS_EXAMPLE_ORG_LDIF);
@RegisterExtension
private static final LdapServer infosupportServer = new LdapServer(USERS_INFOSUPPORT_COM_LDIF, "infosupport.com", "dc=infosupport," +
"dc=com");

@Test
public void testNoConnection() {
void testNoConnection() {
exampleServer.disableAnonymousAccess();
try {
LdapSettingsManager settingsManager = new LdapSettingsManager(
@@ -58,7 +59,7 @@ public class DefaultLdapAuthenticatorIT {
}

@Test
public void testSimple() {
void testSimple() {
LdapSettingsManager settingsManager = new LdapSettingsManager(
LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
@@ -82,7 +83,7 @@ public class DefaultLdapAuthenticatorIT {
}

@Test
public void testSimpleMultiLdap() {
void testSimpleMultiLdap() {
LdapSettingsManager settingsManager = new LdapSettingsManager(
LdapSettingsFactory.generateAuthenticationSettings(exampleServer, infosupportServer, LdapContextFactory.AUTH_METHOD_SIMPLE).asConfig());
DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());
@@ -115,7 +116,7 @@ public class DefaultLdapAuthenticatorIT {
}

@Test
public void testSasl() {
void testSasl() {
MapSettings mapSettings = LdapSettingsFactory.generateAuthenticationSettings(exampleServer, null, LdapContextFactory.AUTH_METHOD_DIGEST_MD5);
//set sasl QoP properties as per https://docs.oracle.com/javase/jndi/tutorial/ldap/security/digest.html
mapSettings.setProperty("ldap.saslQop", "auth")
@@ -140,7 +141,7 @@ public class DefaultLdapAuthenticatorIT {
}

@Test
public void testSaslMultipleLdap() {
void testSaslMultipleLdap() {
LdapSettingsManager settingsManager = new LdapSettingsManager(
LdapSettingsFactory.generateAuthenticationSettings(exampleServer, infosupportServer, LdapContextFactory.AUTH_METHOD_CRAM_MD5).asConfig());
DefaultLdapAuthenticator authenticator = new DefaultLdapAuthenticator(settingsManager.getContextFactories(), settingsManager.getUserMappings());

+ 15
- 2
server/sonar-auth-ldap/src/it/java/org/sonar/auth/ldap/server/LdapServer.java View File

@@ -19,10 +19,13 @@
*/
package org.sonar.auth.ldap.server;

import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ldap.ApacheDS;

public class LdapServer extends ExternalResource {
public class LdapServer extends ExternalResource implements BeforeAllCallback, AfterAllCallback {

private ApacheDS server;
private String ldif;
@@ -40,11 +43,21 @@ public class LdapServer extends ExternalResource {
}

@Override
protected void before() throws Throwable {
public void beforeAll(ExtensionContext extensionContext) throws Exception {
before();
}

@Override
protected void before() throws Exception {
server = ApacheDS.start(realm, baseDn);
server.importLdif(LdapServer.class.getResourceAsStream(ldif));
}

@Override
public void afterAll(ExtensionContext extensionContext) throws Exception {
after();
}

@Override
protected void after() {
try {

+ 2
- 0
server/sonar-ce-task-projectanalysis/build.gradle View File

@@ -52,6 +52,7 @@ dependencies {
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.assertj:assertj-guava'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-params'
testImplementation 'org.reflections:reflections'
testImplementation 'org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures'
testImplementation project(':sonar-testing-harness')
@@ -59,6 +60,7 @@ dependencies {

testFixturesApi 'junit:junit'
testFixturesApi 'org.assertj:assertj-core'
testFixturesApi 'org.junit.jupiter:junit-jupiter-api'
testFixturesApi 'org.mockito:mockito-core'
testFixturesApi testFixtures(project(':server:sonar-ce-task'))


+ 21
- 21
server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistDuplicationDataStepIT.java View File

@@ -20,9 +20,9 @@
package org.sonar.ce.task.projectanalysis.step;

import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.measures.Metric;
import org.sonar.api.utils.System2;
import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
@@ -44,7 +44,7 @@ import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;

public class PersistDuplicationDataStepIT extends BaseStepTest {
class PersistDuplicationDataStepIT extends BaseStepJUnit5Test {

private static final int ROOT_REF = 1;
private static final String PROJECT_KEY = "PROJECT_KEY";
@@ -58,10 +58,10 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
private static final String FILE_2_KEY = "FILE_2_KEY";
private static final String FILE_2_UUID = "u3";

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule()
@RegisterExtension
private final DbTester db = DbTester.create(System2.INSTANCE);
@RegisterExtension
private final TreeRootHolderRule treeRootHolder = new TreeRootHolderRule()
.setRoot(
builder(PROJECT, ROOT_REF).setKey(PROJECT_KEY).setUuid(PROJECT_UUID)
.addChildren(
@@ -71,15 +71,15 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
.build())
.build());

@Rule
public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
@Rule
public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule();
@RegisterExtension
private final MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
@RegisterExtension
private final DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
@RegisterExtension
private final MetricRepositoryRule metricRepository = new MetricRepositoryRule();

@Before
public void setUp() {
@BeforeEach
void setUp() {
MetricDto metric = db.measures().insertMetric(m -> m.setKey(DUPLICATIONS_DATA_KEY).setValueType(Metric.ValueType.STRING.name()));
insertComponent(PROJECT_KEY, PROJECT_UUID);
insertComponent(FILE_1_KEY, FILE_1_UUID);
@@ -94,7 +94,7 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
}

@Test
public void nothing_to_persist_when_no_duplication() {
void nothing_to_persist_when_no_duplication() {
TestComputationStepContext context = new TestComputationStepContext();

underTest().execute(context);
@@ -104,7 +104,7 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
}

@Test
public void compute_duplications_on_same_file() {
void compute_duplications_on_same_file() {
duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 5), new TextBlock(6, 10));
TestComputationStepContext context = new TestComputationStepContext();

@@ -117,7 +117,7 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
}

@Test
public void compute_duplications_on_different_files() {
void compute_duplications_on_different_files() {
duplicationRepository.addDuplication(FILE_1_REF, new TextBlock(1, 5), FILE_2_REF, new TextBlock(6, 10));
TestComputationStepContext context = new TestComputationStepContext();

@@ -131,7 +131,7 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
}

@Test
public void compute_duplications_on_unchanged_file() {
void compute_duplications_on_unchanged_file() {
duplicationRepository.addExtendedProjectDuplication(FILE_1_REF, new TextBlock(1, 5), FILE_2_REF, new TextBlock(6, 10));
TestComputationStepContext context = new TestComputationStepContext();

@@ -145,7 +145,7 @@ public class PersistDuplicationDataStepIT extends BaseStepTest {
}

@Test
public void compute_duplications_on_different_projects() {
void compute_duplications_on_different_projects() {
String fileKeyFromOtherProject = "PROJECT2_KEY:file2";
duplicationRepository.addCrossProjectDuplication(FILE_1_REF, new TextBlock(1, 5), fileKeyFromOtherProject, new TextBlock(6, 10));
TestComputationStepContext context = new TestComputationStepContext();

+ 7
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java View File

@@ -32,6 +32,8 @@ import java.util.Objects;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -39,7 +41,7 @@ import org.sonar.core.util.CloseableIterator;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode;

public class BatchReportReaderRule implements TestRule, BatchReportReader {
public class BatchReportReaderRule implements TestRule, BatchReportReader, AfterEachCallback {
private ScannerReport.Metadata metadata;
private List<String> scannerLogs;
private List<ScannerReport.ActiveRule> activeRules = new ArrayList<>();
@@ -320,4 +322,8 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader {
return this;
}

@Override
public void afterEach(ExtensionContext context) {
clear();
}
}

+ 47
- 46
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentTreeBuilderTest.java View File

@@ -29,9 +29,10 @@ import java.util.Optional;
import java.util.Random;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.core.component.ComponentKeys;
import org.sonar.scanner.protocol.output.ScannerReport;
@@ -51,7 +52,7 @@ import static org.sonar.scanner.protocol.output.ScannerReport.Component.Componen
import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNRECOGNIZED;
import static org.sonar.scanner.protocol.output.ScannerReport.Component.newBuilder;

public class ComponentTreeBuilderTest {
class ComponentTreeBuilderTest {

private static final ComponentKeyGenerator KEY_GENERATOR = (projectKey, path) -> "generated_" + ComponentKeys.createEffectiveKey(projectKey, path);
private static final UnaryOperator<String> UUID_SUPPLIER = (componentKey) -> componentKey + "_uuid";
@@ -61,13 +62,13 @@ public class ComponentTreeBuilderTest {
private static final ProjectAttributes SOME_PROJECT_ATTRIBUTES = new ProjectAttributes(
randomAlphabetic(20), new Random().nextBoolean() ? null : randomAlphabetic(12), "1def5123");

@Rule
public ScannerComponentProvider scannerComponentProvider = new ScannerComponentProvider();
@RegisterExtension
private final ScannerComponentProvider scannerComponentProvider = new ScannerComponentProvider();

private Project projectInDb = Project.from(newPrivateProjectDto(UUID_SUPPLIER.apply("K1")).setKey("K1").setDescription(null));
private final Project projectInDb = Project.from(newPrivateProjectDto(UUID_SUPPLIER.apply("K1")).setKey("K1").setDescription(null));

@Test
public void build_throws_IAE_for_all_types_except_PROJECT_and_FILE() {
void build_throws_IAE_for_all_types_except_PROJECT_and_FILE() {
Arrays.stream(ScannerReport.Component.ComponentType.values())
.filter((type) -> type != UNRECOGNIZED)
.filter((type) -> !REPORT_TYPES.contains(type))
@@ -96,7 +97,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void build_throws_IAE_if_root_is_not_PROJECT() {
void build_throws_IAE_if_root_is_not_PROJECT() {
Arrays.stream(ScannerReport.Component.ComponentType.values())
.filter((type) -> type != UNRECOGNIZED)
.filter((type) -> !REPORT_TYPES.contains(type))
@@ -113,7 +114,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void by_default_project_fields_are_loaded_from_report() {
void by_default_project_fields_are_loaded_from_report() {
String nameInReport = "the name";
String descriptionInReport = "the desc";
String buildString = randomAlphabetic(21);
@@ -138,7 +139,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_name_is_loaded_from_db_if_absent_from_report() {
void project_name_is_loaded_from_db_if_absent_from_report() {
Component root = call(newBuilder()
.setType(PROJECT)
.build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
@@ -147,7 +148,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_name_is_loaded_from_report_if_present_and_on_main_branch() {
void project_name_is_loaded_from_report_if_present_and_on_main_branch() {
String reportName = randomAlphabetic(5);
ScannerReport.Component reportProject = newBuilder()
.setType(PROJECT)
@@ -160,7 +161,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_name_is_loaded_from_db_if_not_on_main_branch() {
void project_name_is_loaded_from_db_if_not_on_main_branch() {
String reportName = randomAlphabetic(5);
ScannerReport.Component reportProject = newBuilder()
.setType(PROJECT)
@@ -174,7 +175,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_description_is_loaded_from_db_if_absent_from_report() {
void project_description_is_loaded_from_db_if_absent_from_report() {
Component root = call(newBuilder()
.setType(PROJECT)
.build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
@@ -183,7 +184,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_description_is_loaded_from_report_if_present_and_on_main_branch() {
void project_description_is_loaded_from_report_if_present_and_on_main_branch() {
String reportDescription = randomAlphabetic(5);
ScannerReport.Component reportProject = newBuilder()
.setType(PROJECT)
@@ -196,7 +197,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_description_is_loaded_from_db_if_not_on_main_branch() {
void project_description_is_loaded_from_db_if_not_on_main_branch() {
String reportDescription = randomAlphabetic(5);
ScannerReport.Component reportProject = newBuilder()
.setType(PROJECT)
@@ -209,7 +210,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void project_scmPath_is_empty_if_scmBasePath_is_empty() {
void project_scmPath_is_empty_if_scmBasePath_is_empty() {
Component root = call(newBuilder()
.setType(PROJECT)
.build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
@@ -218,7 +219,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void projectAttributes_is_constructor_argument() {
void projectAttributes_is_constructor_argument() {
Component root = call(newBuilder()
.setType(PROJECT)
.build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
@@ -227,7 +228,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void any_component_with_projectRelativePath_has_this_value_as_scmPath_if_scmBasePath_is_empty() {
void any_component_with_projectRelativePath_has_this_value_as_scmPath_if_scmBasePath_is_empty() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -254,7 +255,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void any_component_with_projectRelativePath_has_this_value_appended_to_scmBasePath_and_a_slash_as_scmPath_if_scmBasePath_is_not_empty() {
void any_component_with_projectRelativePath_has_this_value_appended_to_scmBasePath_and_a_slash_as_scmPath_if_scmBasePath_is_not_empty() {
ScannerReport.Component project = createProject();
String scmBasePath = randomAlphabetic(10);

@@ -285,7 +286,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void keys_of_directory_and_file_are_generated() {
void keys_of_directory_and_file_are_generated() {
ScannerReport.Component project = createProject();

Component root = call(project);
@@ -302,7 +303,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void modules_are_not_created() {
void modules_are_not_created() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -322,7 +323,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void folder_hierarchy_is_created() {
void folder_hierarchy_is_created() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -371,7 +372,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void collapse_directories_from_root() {
void collapse_directories_from_root() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -399,7 +400,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void directories_are_collapsed() {
void directories_are_collapsed() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -426,7 +427,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void names_of_directory_and_file_are_based_on_the_path() {
void names_of_directory_and_file_are_based_on_the_path() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -452,7 +453,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void create_full_hierarchy_of_directories() {
void create_full_hierarchy_of_directories() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey(projectInDb.getKey())
@@ -506,7 +507,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void keys_of_directory_and_files_includes_always_root_project() {
void keys_of_directory_and_files_includes_always_root_project() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey("project 1")
@@ -520,7 +521,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void uuids_are_provided_by_supplier() {
void uuids_are_provided_by_supplier() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey("c1")
@@ -544,7 +545,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void files_have_markedAsUnchanged_flag() {
void files_have_markedAsUnchanged_flag() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey("c1")
@@ -569,7 +570,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void issues_are_relocated_from_directories_and_modules_to_root() {
void issues_are_relocated_from_directories_and_modules_to_root() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setKey("c1")
@@ -587,7 +588,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void descriptions_of_module_directory_and_file_are_null_if_absent_from_report() {
void descriptions_of_module_directory_and_file_are_null_if_absent_from_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -609,7 +610,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void descriptions_of_module_directory_and_file_are_null_if_empty_in_report() {
void descriptions_of_module_directory_and_file_are_null_if_empty_in_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -633,7 +634,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void descriptions_of_module_directory_and_file_are_set_from_report_if_present() {
void descriptions_of_module_directory_and_file_are_set_from_report_if_present() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -655,7 +656,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void only_nb_of_lines_is_mandatory_on_file_attributes() {
void only_nb_of_lines_is_mandatory_on_file_attributes() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -676,7 +677,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void language_file_attributes_is_null_if_empty_in_report() {
void language_file_attributes_is_null_if_empty_in_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -697,7 +698,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void file_attributes_are_fully_loaded_from_report() {
void file_attributes_are_fully_loaded_from_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -720,7 +721,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void throw_IAE_if_lines_is_absent_from_report() {
void throw_IAE_if_lines_is_absent_from_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -737,7 +738,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void throw_IAE_if_lines_is_zero_in_report() {
void throw_IAE_if_lines_is_zero_in_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -755,7 +756,7 @@ public class ComponentTreeBuilderTest {
}

@Test
public void throw_IAE_if_lines_is_negative_in_report() {
void throw_IAE_if_lines_is_negative_in_report() {
ScannerReport.Component project = newBuilder()
.setType(PROJECT)
.setRef(1)
@@ -772,14 +773,9 @@ public class ComponentTreeBuilderTest {
.hasMessage("File 'src/js/Foo.js' has no line");
}

private static class ScannerComponentProvider extends ExternalResource implements Function<Integer, ScannerReport.Component> {
private static class ScannerComponentProvider implements Function<Integer, ScannerReport.Component>, BeforeEachCallback {
private final Map<Integer, ScannerReport.Component> components = new HashMap<>();

@Override
protected void before() {
clear();
}

public void clear() {
components.clear();
}
@@ -795,6 +791,11 @@ public class ComponentTreeBuilderTest {
checkArgument(existing == null, "Component %s already set for ref %s", existing, component.getRef());
return component;
}

@Override
public void beforeEach(ExtensionContext extensionContext) {
clear();
}
}

private Component call(ScannerReport.Component project) {

+ 14
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/duplication/DuplicationRepositoryRule.java View File

@@ -25,6 +25,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ComponentProvider;
@@ -35,7 +38,7 @@ import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

public class DuplicationRepositoryRule extends ExternalResource implements DuplicationRepository {
public class DuplicationRepositoryRule extends ExternalResource implements DuplicationRepository, BeforeEachCallback, AfterEachCallback {
@CheckForNull
private final ComponentProvider componentProvider;
private DuplicationRepositoryImpl delegate;
@@ -59,11 +62,21 @@ public class DuplicationRepositoryRule extends ExternalResource implements Dupli
return new DuplicationRepositoryRule();
}

@Override
public void beforeEach(ExtensionContext extensionContext) {
before();
}

@Override
protected void before() {
this.delegate = new DuplicationRepositoryImpl();
}

@Override
public void afterEach(ExtensionContext extensionContext) {
after();
}

@Override
protected void after() {
if (this.componentProvider != null) {

+ 14
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/filemove/MutableMovedFilesRepositoryRule.java View File

@@ -23,14 +23,27 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.projectanalysis.component.Component;

public class MutableMovedFilesRepositoryRule extends ExternalResource implements MutableMovedFilesRepository {
public class MutableMovedFilesRepositoryRule extends ExternalResource
implements MutableMovedFilesRepository, BeforeEachCallback, AfterEachCallback {
@CheckForNull
private MutableMovedFilesRepository delegate;
private final Set<Component> componentsWithOriginal = new HashSet<>();

@Override
public void afterEach(ExtensionContext extensionContext) {
after();
}

@Override
public void beforeEach(ExtensionContext extensionContext) {
before();
}
@Override
protected void before() {
this.delegate = new MutableMovedFilesRepositoryImpl();

+ 18
- 19
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/coverage/CoverageUtilsTest.java View File

@@ -22,9 +22,10 @@ package org.sonar.ce.task.projectanalysis.formula.coverage;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.formula.CounterInitializationContext;
import org.sonar.ce.task.projectanalysis.measure.Measure;
@@ -36,47 +37,46 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonar.ce.task.projectanalysis.formula.coverage.CoverageUtils.getLongMeasureValue;
import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;

public class CoverageUtilsTest {
class CoverageUtilsTest {

private static final String SOME_METRIC_KEY = "some key";
public static final double DEFAULT_VARIATION = 0d;

@Rule
public CounterInitializationContextRule fileAggregateContext = new CounterInitializationContextRule();
@RegisterExtension
private final CounterInitializationContextRule fileAggregateContext = new CounterInitializationContextRule();

@Test
public void verify_calculate_coverage() {
void verify_calculate_coverage() {
assertThat(CoverageUtils.calculateCoverage(5, 10)).isEqualTo(50d);
}

@Test
public void getLongMeasureValue_returns_0_if_measure_does_not_exist() {
void getLongMeasureValue_returns_0_if_measure_does_not_exist() {
assertThat(getLongMeasureValue(fileAggregateContext, SOME_METRIC_KEY)).isZero();
}

@Test
public void getLongMeasureValue_returns_0_if_measure_is_NO_VALUE() {
void getLongMeasureValue_returns_0_if_measure_is_NO_VALUE() {
fileAggregateContext.put(SOME_METRIC_KEY, newMeasureBuilder().createNoValue());

assertThat(getLongMeasureValue(fileAggregateContext, SOME_METRIC_KEY)).isZero();
}

@Test
public void getLongMeasureValue_returns_value_if_measure_is_INT() {
void getLongMeasureValue_returns_value_if_measure_is_INT() {
fileAggregateContext.put(SOME_METRIC_KEY, newMeasureBuilder().create(152));

assertThat(getLongMeasureValue(fileAggregateContext, SOME_METRIC_KEY)).isEqualTo(152L);
}

@Test
public void getLongMeasureValue_returns_value_if_measure_is_LONG() {
void getLongMeasureValue_returns_value_if_measure_is_LONG() {
fileAggregateContext.put(SOME_METRIC_KEY, newMeasureBuilder().create(152L));

assertThat(getLongMeasureValue(fileAggregateContext, SOME_METRIC_KEY)).isEqualTo(152L);
}

@Test
public void getLongMeasureValue_throws_ISE_if_measure_is_DOUBLE() {
void getLongMeasureValue_throws_ISE_if_measure_is_DOUBLE() {
assertThatThrownBy(() -> {
fileAggregateContext.put(SOME_METRIC_KEY, newMeasureBuilder().create(152d, 1));
getLongMeasureValue(fileAggregateContext, SOME_METRIC_KEY);
@@ -85,7 +85,7 @@ public class CoverageUtilsTest {
.hasMessage("value can not be converted to long because current value type is a DOUBLE");
}

private static class CounterInitializationContextRule extends ExternalResource implements CounterInitializationContext {
private static class CounterInitializationContextRule implements CounterInitializationContext, AfterEachCallback {
private final Map<String, Measure> measures = new HashMap<>();

public CounterInitializationContextRule put(String metricKey, Measure measure) {
@@ -96,11 +96,6 @@ public class CoverageUtilsTest {
return this;
}

@Override
protected void after() {
measures.clear();
}

@Override
public Component getLeaf() {
throw new UnsupportedOperationException("getFile is not supported");
@@ -111,5 +106,9 @@ public class CoverageUtilsTest {
return Optional.ofNullable(measures.get(metricKey));
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
measures.clear();
}
}
}

+ 7
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/FillComponentIssuesVisitorRule.java View File

@@ -21,6 +21,8 @@ package org.sonar.ce.task.projectanalysis.issue;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -37,7 +39,7 @@ import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order
/**
* This rule can be used when testing a visitor that depends on {@link ComponentIssuesRepository}.
*/
public class FillComponentIssuesVisitorRule extends TypeAwareVisitorAdapter implements TestRule {
public class FillComponentIssuesVisitorRule extends TypeAwareVisitorAdapter implements TestRule, AfterEachCallback {

private MutableComponentIssuesRepository issuesRepository = new ComponentIssuesRepositoryImpl();
private final TreeRootHolder treeRootHolder;
@@ -76,4 +78,8 @@ public class FillComponentIssuesVisitorRule extends TypeAwareVisitorAdapter impl
issuesRepository.setIssues(component, issues.get(component));
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
issues = ArrayListMultimap.create();
}
}

+ 25
- 25
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueAssignerTest.java View File

@@ -21,11 +21,11 @@ package org.sonar.ce.task.projectanalysis.issue;

import java.util.Arrays;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.event.Level;
import org.sonar.api.testfixtures.log.LogTester;
import org.sonar.api.testfixtures.log.LogTesterJUnit5;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.scm.Changeset;
@@ -43,31 +43,31 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;

public class IssueAssignerTest {
class IssueAssignerTest {

private static final int FILE_REF = 1;
private static final Component FILE = builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY").setUuid("FILE_UUID").build();

@Rule
public LogTester logTester = new LogTester();
@RegisterExtension
private final LogTesterJUnit5 logTester = new LogTesterJUnit5();

@Rule
public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
@RegisterExtension
private final ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();

@Rule
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule().setAnalysisDate(123456789L);
@RegisterExtension
private final AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule().setAnalysisDate(123456789L);

private final ScmAccountToUser scmAccountToUser = mock(ScmAccountToUser.class);
private final DefaultAssignee defaultAssignee = mock(DefaultAssignee.class);
private final IssueAssigner underTest = new IssueAssigner(analysisMetadataHolder, scmInfoRepository, scmAccountToUser, defaultAssignee, new IssueFieldsSetter());

@Before
public void before() {
@BeforeEach
void before() {
logTester.setLevel(Level.DEBUG);
}

@Test
public void do_not_set_author_if_no_changeset() {
void do_not_set_author_if_no_changeset() {
DefaultIssue issue = newIssueOnLines(1);

underTest.onIssue(FILE, issue);
@@ -76,7 +76,7 @@ public class IssueAssignerTest {
}

@Test
public void set_author_of_new_issue_if_changeset() {
void set_author_of_new_issue_if_changeset() {
setSingleChangeset("john", 123456789L, "rev-1");
DefaultIssue issue = newIssueOnLines(1);

@@ -86,7 +86,7 @@ public class IssueAssignerTest {
}

@Test
public void do_not_reset_author_if_already_set() {
void do_not_reset_author_if_already_set() {
setSingleChangeset("john", 123456789L, "rev-1");
DefaultIssue issue = newIssueOnLines(1)
.setAuthorLogin("jane");
@@ -97,7 +97,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_but_do_not_set_author_if_too_long() {
void assign_but_do_not_set_author_if_too_long() {
String scmAuthor = range(0, 256).mapToObj(i -> "s").collect(joining());
addScmUser(scmAuthor, buildUserId("u123", "John C"));
setSingleChangeset(scmAuthor, 123456789L, "rev-1");
@@ -113,7 +113,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_new_issue_to_author_of_change() {
void assign_new_issue_to_author_of_change() {
addScmUser("john", buildUserId("u123", "john"));
setSingleChangeset("john", 123456789L, "rev-1");
DefaultIssue issue = newIssueOnLines(1);
@@ -125,7 +125,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_new_issue_to_default_assignee_if_author_not_found() {
void assign_new_issue_to_default_assignee_if_author_not_found() {
setSingleChangeset("john", 123456789L, "rev-1");
when(defaultAssignee.loadDefaultAssigneeUserId()).thenReturn(new UserIdDto("u1234", "john"));
DefaultIssue issue = newIssueOnLines(1);
@@ -137,7 +137,7 @@ public class IssueAssignerTest {
}

@Test
public void do_not_assign_new_issue_if_no_author_in_changeset() {
void do_not_assign_new_issue_if_no_author_in_changeset() {
setSingleChangeset(null, 123456789L, "rev-1");
DefaultIssue issue = newIssueOnLines(1);

@@ -148,7 +148,7 @@ public class IssueAssignerTest {
}

@Test
public void do_not_assign_issue_if_unassigned_but_already_authored() {
void do_not_assign_issue_if_unassigned_but_already_authored() {
addScmUser("john", buildUserId("u1234", "john"));
setSingleChangeset("john", 123456789L, "rev-1");
DefaultIssue issue = newIssueOnLines(1)
@@ -162,7 +162,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_to_last_committer_of_file_if_issue_is_global_to_file() {
void assign_to_last_committer_of_file_if_issue_is_global_to_file() {
addScmUser("henry", buildUserId("u123", "Henry V"));
Changeset changeset1 = Changeset.newChangesetBuilder()
.setAuthor("john")
@@ -186,7 +186,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_to_default_assignee_if_no_author() {
void assign_to_default_assignee_if_no_author() {
DefaultIssue issue = newIssueOnLines();

when(defaultAssignee.loadDefaultAssigneeUserId()).thenReturn(new UserIdDto("u123", "john"));
@@ -197,7 +197,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_to_default_assignee_if_no_scm_on_issue_locations() {
void assign_to_default_assignee_if_no_scm_on_issue_locations() {
addScmUser("john", buildUserId("u123", "John C"));
Changeset changeset = Changeset.newChangesetBuilder()
.setAuthor("john")
@@ -214,7 +214,7 @@ public class IssueAssignerTest {
}

@Test
public void assign_to_author_of_the_most_recent_change_in_all_issue_locations() {
void assign_to_author_of_the_most_recent_change_in_all_issue_locations() {
addScmUser("john", buildUserId("u1", "John"));
addScmUser("jane", buildUserId("u2", "Jane"));
Changeset commit1 = Changeset.newChangesetBuilder()

+ 20
- 21
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssuesRepositoryVisitorTest.java View File

@@ -19,9 +19,9 @@
*/
package org.sonar.ce.task.projectanalysis.issue;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.core.issue.DefaultIssue;
@@ -30,39 +30,38 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;

public class IssuesRepositoryVisitorTest {
static final String FILE_UUID = "FILE_UUID";
static final String FILE_KEY = "FILE_KEY";
static final int FILE_REF = 2;
static final Component FILE = builder(Component.Type.FILE, FILE_REF)
class IssuesRepositoryVisitorTest {
private static final String FILE_UUID = "FILE_UUID";
private static final String FILE_KEY = "FILE_KEY";
private static final int FILE_REF = 2;
private static final Component FILE = builder(Component.Type.FILE, FILE_REF)
.setKey(FILE_KEY)
.setUuid(FILE_UUID)
.build();

static final String PROJECT_KEY = "PROJECT_KEY";
static final String PROJECT_UUID = "PROJECT_UUID";
static final int PROJECT_REF = 1;
static final Component PROJECT = builder(Component.Type.PROJECT, PROJECT_REF)
private static final String PROJECT_KEY = "PROJECT_KEY";
private static final String PROJECT_UUID = "PROJECT_UUID";
private static final int PROJECT_REF = 1;
private static final Component PROJECT = builder(Component.Type.PROJECT, PROJECT_REF)
.setKey(PROJECT_KEY)
.setUuid(PROJECT_UUID)
.addChildren(FILE)
.build();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@RegisterExtension
private final TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public ComponentIssuesRepositoryRule componentIssuesRepository = new ComponentIssuesRepositoryRule(treeRootHolder);
private final ComponentIssuesRepositoryRule componentIssuesRepository = new ComponentIssuesRepositoryRule(treeRootHolder);

IssuesRepositoryVisitor underTest = new IssuesRepositoryVisitor(componentIssuesRepository);
private final IssuesRepositoryVisitor underTest = new IssuesRepositoryVisitor(componentIssuesRepository);

@Before
public void setUp() {
@BeforeEach
void setUp() {
treeRootHolder.setRoot(PROJECT);
}

@Test
public void feed_component_issues_repo() {
void feed_component_issues_repo() {
DefaultIssue i1 = mock(DefaultIssue.class);
DefaultIssue i2 = mock(DefaultIssue.class);

@@ -75,7 +74,7 @@ public class IssuesRepositoryVisitorTest {
}

@Test
public void empty_component_issues_repo_when_no_issue() {
void empty_component_issues_repo_when_no_issue() {
DefaultIssue i1 = mock(DefaultIssue.class);
DefaultIssue i2 = mock(DefaultIssue.class);


+ 7
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryRule.java View File

@@ -23,6 +23,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.api.rule.RuleKey;
import org.sonar.db.DbSession;
@@ -30,7 +32,7 @@ import org.sonar.db.DbSession;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

public class RuleRepositoryRule extends ExternalResource implements RuleRepository {
public class RuleRepositoryRule extends ExternalResource implements RuleRepository, AfterEachCallback {

private final Map<RuleKey, Rule> rulesByKey = new HashMap<>();
private final Map<String, Rule> rulesByUuid = new HashMap<>();
@@ -90,4 +92,8 @@ public class RuleRepositoryRule extends ExternalResource implements RuleReposito
newExternalRulesById.computeIfAbsent(ruleKey, k -> ruleSupplier.get());
}

@Override
public void afterEach(ExtensionContext context) {
after();
}
}

+ 44
- 46
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactoryTest.java View File

@@ -20,20 +20,20 @@
package org.sonar.ce.task.projectanalysis.issue;

import com.google.common.collect.Iterators;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
@@ -70,8 +70,7 @@ import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY;
import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY;
import static org.sonar.scanner.protocol.output.ScannerReport.MessageFormattingType.CODE;

@RunWith(DataProviderRunner.class)
public class TrackerRawInputFactoryTest {
class TrackerRawInputFactoryTest {

private static final String FILE_UUID = "fake_uuid";
private static final String ANOTHER_FILE_UUID = "another_fake_uuid";
@@ -82,14 +81,14 @@ public class TrackerRawInputFactoryTest {
private static final int ANOTHER_FILE_REF = 4;
private static final String TEST_CONTEXT_KEY = "test_context_key";

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT);
@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
@Rule
public ActiveRulesHolderRule activeRulesHolder = new ActiveRulesHolderRule();
@Rule
public RuleRepositoryRule ruleRepository = new RuleRepositoryRule();
@RegisterExtension
private final TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT);
@RegisterExtension
private final BatchReportReaderRule reportReader = new BatchReportReaderRule();
@RegisterExtension
private final ActiveRulesHolderRule activeRulesHolder = new ActiveRulesHolderRule();
@RegisterExtension
private final RuleRepositoryRule ruleRepository = new RuleRepositoryRule();

private static final ReportComponent FILE = ReportComponent.builder(Component.Type.FILE, FILE_REF).setUuid(FILE_UUID).build();
private static final ReportComponent ANOTHER_FILE = ReportComponent.builder(Component.Type.FILE, ANOTHER_FILE_REF).setUuid(ANOTHER_FILE_UUID).build();
@@ -100,14 +99,14 @@ public class TrackerRawInputFactoryTest {
private final TrackerRawInputFactory underTest = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash,
issueFilter, ruleRepository, activeRulesHolder);

@Before
public void before() {
@BeforeEach
void before() {
when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line"));
when(issueFilter.accept(any(), eq(FILE))).thenReturn(true);
}

@Test
public void load_source_hash_sequences() {
void load_source_hash_sequences() {
Input<DefaultIssue> input = underTest.create(FILE);

assertThat(input.getLineHashSequence()).isNotNull();
@@ -119,7 +118,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void load_source_hash_sequences_only_on_files() {
void load_source_hash_sequences_only_on_files() {
Input<DefaultIssue> input = underTest.create(PROJECT);

assertThat(input.getLineHashSequence()).isNotNull();
@@ -127,7 +126,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void load_issues_from_report() {
void load_issues_from_report() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "name", r -> r.addDefaultImpact(MAINTAINABILITY, LOW));
@@ -177,7 +176,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void load_issues_from_report_with_locations() {
void load_issues_from_report_with_locations() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "name");
@@ -223,7 +222,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void load_issues_from_report_with_rule_description_context_key() {
void load_issues_from_report_with_rule_description_context_key() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "name");
@@ -246,7 +245,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void create_whenImpactIsNotDefinedAtRuleLevel_shouldDiscardImpacts() {
void create_whenImpactIsNotDefinedAtRuleLevel_shouldDiscardImpacts() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "name", r -> r.addDefaultImpact(MAINTAINABILITY, LOW));
@@ -269,7 +268,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void set_rule_name_as_message_when_issue_message_from_report_is_empty() {
void set_rule_name_as_message_when_issue_message_from_report_is_empty() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "Rule 1");
@@ -295,7 +294,7 @@ public class TrackerRawInputFactoryTest {

// SONAR-10781
@Test
public void load_issues_from_report_missing_secondary_location_component() {
void load_issues_from_report_missing_secondary_location_component() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "name");
@@ -338,9 +337,9 @@ public class TrackerRawInputFactoryTest {
assertThat(locations.getFlow(0).getLocation(1).getComponentId()).isEqualTo(ANOTHER_FILE_UUID);
}

@Test
@UseDataProvider("ruleTypeAndStatusByIssueType")
public void load_external_issues_from_report(IssueType issueType, RuleType expectedRuleType, String expectedStatus) {
@ParameterizedTest
@MethodSource("ruleTypeAndStatusByIssueType")
void load_external_issues_from_report(IssueType issueType, RuleType expectedRuleType, String expectedStatus) {
registerRule(RuleKey.of("external_eslint", "S001"), "rule", r -> r.addDefaultImpact(MAINTAINABILITY, LOW));
ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder()
.setTextRange(newTextRange(2))
@@ -391,19 +390,18 @@ public class TrackerRawInputFactoryTest {
assertThat(issue.impacts()).containsExactlyEntriesOf(Map.of(MAINTAINABILITY, org.sonar.api.issue.impact.Severity.MEDIUM));
}

@DataProvider
public static Object[][] ruleTypeAndStatusByIssueType() {
return new Object[][]{
{IssueType.CODE_SMELL, RuleType.CODE_SMELL, STATUS_OPEN},
{IssueType.BUG, RuleType.BUG, STATUS_OPEN},
{IssueType.VULNERABILITY, RuleType.VULNERABILITY, STATUS_OPEN},
{IssueType.SECURITY_HOTSPOT, RuleType.SECURITY_HOTSPOT, STATUS_TO_REVIEW}
};
private static Stream<Arguments> ruleTypeAndStatusByIssueType() {
return Stream.of(
Arguments.of(IssueType.CODE_SMELL, RuleType.CODE_SMELL, STATUS_OPEN),
Arguments.of(IssueType.BUG, RuleType.BUG, STATUS_OPEN),
Arguments.of(IssueType.VULNERABILITY, RuleType.VULNERABILITY, STATUS_OPEN),
Arguments.of(IssueType.SECURITY_HOTSPOT, RuleType.SECURITY_HOTSPOT, STATUS_TO_REVIEW)
);
}

@Test
@UseDataProvider("ruleTypeAndStatusByIssueType")
public void load_external_issues_from_report_with_default_effort(IssueType issueType, RuleType expectedRuleType, String expectedStatus) {
@ParameterizedTest
@MethodSource("ruleTypeAndStatusByIssueType")
void load_external_issues_from_report_with_default_effort(IssueType issueType, RuleType expectedRuleType, String expectedStatus) {
registerRule(RuleKey.of("external_eslint", "S001"), "rule");
ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder()
.setTextRange(newTextRange(2))
@@ -435,7 +433,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void create_whenSeverityAndTypeNotProvided_shouldTakeFromTheRule() {
void create_whenSeverityAndTypeNotProvided_shouldTakeFromTheRule() {
registerRule(RuleKey.of("external_eslint", "S001"), "rule", r -> {
r.setType(RuleType.BUG);
r.setSeverity(Severity.MAJOR);
@@ -453,7 +451,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void create_whenSeverityAndTypeNotProvidedByIssueAndRule_shouldTakeFromTheRuleImpact() {
void create_whenSeverityAndTypeNotProvidedByIssueAndRule_shouldTakeFromTheRuleImpact() {
registerRule(RuleKey.of("external_eslint", "S001"), "rule",
r -> r.addDefaultImpact(MAINTAINABILITY, org.sonar.api.issue.impact.Severity.MEDIUM));
ScannerReport.ExternalIssue reportIssue = createIssue(null, null);
@@ -487,7 +485,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void excludes_issues_on_inactive_rules() {
void excludes_issues_on_inactive_rules() {
RuleKey ruleKey = RuleKey.of("java", "S001");
ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
.setTextRange(newTextRange(2))
@@ -505,7 +503,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void filter_excludes_issues_from_report() {
void filter_excludes_issues_from_report() {
RuleKey ruleKey = RuleKey.of("java", "S001");
markRuleAsActive(ruleKey);
registerRule(ruleKey, "name");
@@ -526,7 +524,7 @@ public class TrackerRawInputFactoryTest {
}

@Test
public void exclude_issues_on_common_rules() {
void exclude_issues_on_common_rules() {
RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "S001");
markRuleAsActive(ruleKey);
ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()

+ 9
- 9
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/MeasureComputersHolderRule.java View File

@@ -21,28 +21,23 @@ package org.sonar.ce.task.projectanalysis.measure;

import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.rules.ExternalResource;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.ce.task.projectanalysis.api.measurecomputer.MeasureComputerWrapper;

import static java.util.Objects.requireNonNull;

public class MeasureComputersHolderRule extends ExternalResource implements MeasureComputersHolder {
public class MeasureComputersHolderRule implements MeasureComputersHolder, AfterEachCallback {

private final MeasureComputer.MeasureComputerDefinitionContext context;

private List<MeasureComputerWrapper> measureComputers = new ArrayList<>();
private final List<MeasureComputerWrapper> measureComputers = new ArrayList<>();

public MeasureComputersHolderRule(MeasureComputer.MeasureComputerDefinitionContext context) {
this.context = context;
}

@After
public void tearDown() {
measureComputers.clear();
}

@Override
public Iterable<MeasureComputerWrapper> getMeasureComputers() {
return measureComputers;
@@ -53,4 +48,9 @@ public class MeasureComputersHolderRule extends ExternalResource implements Meas
MeasureComputer.MeasureComputerDefinition definition = measureComputer.define(context);
this.measureComputers.add(new MeasureComputerWrapper(measureComputer, definition));
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
measureComputers.clear();
}
}

+ 16
- 16
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/ViewsMeasureComputersVisitorTest.java View File

@@ -20,8 +20,8 @@
package org.sonar.ce.task.projectanalysis.measure;

import java.util.Arrays;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.api.testfixtures.measure.TestMeasureComputerDefinitionContext;
import org.sonar.ce.task.projectanalysis.api.measurecomputer.MeasureComputerDefinitionImpl;
@@ -45,7 +45,7 @@ import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilde
import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.entryOf;
import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.toEntries;

public class ViewsMeasureComputersVisitorTest {
class ViewsMeasureComputersVisitorTest {

private static final String NEW_METRIC_KEY = "new_metric_key";
private static final String NEW_METRIC_NAME = "new metric name";
@@ -97,25 +97,25 @@ public class ViewsMeasureComputersVisitorTest {
}
};

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@RegisterExtension
private final TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
@RegisterExtension
private final MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(NCLOC)
.add(COMMENT_LINES)
.add(NEW_METRIC);

@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(TREE_WITH_SUB_VIEWS, metricRepository);
@RegisterExtension
private final MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(TREE_WITH_SUB_VIEWS, metricRepository);

@Rule
public MeasureComputersHolderRule measureComputersHolder = new MeasureComputersHolderRule(new TestMeasureComputerDefinitionContext());
@RegisterExtension
private final MeasureComputersHolderRule measureComputersHolder = new MeasureComputersHolderRule(new TestMeasureComputerDefinitionContext());

ComponentIssuesRepository componentIssuesRepository = mock(ComponentIssuesRepository.class);
private final ComponentIssuesRepository componentIssuesRepository = mock(ComponentIssuesRepository.class);

@Test
public void compute_plugin_measure() {
void compute_plugin_measure() {
treeRootHolder.setRoot(TREE_WITH_SUB_VIEWS);

addRawMeasure(PROJECT_VIEW_1_REF, NCLOC_KEY, 10);
@@ -142,7 +142,7 @@ public class ViewsMeasureComputersVisitorTest {
}

@Test
public void compute_plugin_measure_on_views_tree_having_only_one_view_with_a_project_view() {
void compute_plugin_measure_on_views_tree_having_only_one_view_with_a_project_view() {
treeRootHolder.setRoot(TREE_WITH_DIRECT_PROJECT_VIEW);

addRawMeasure(PROJECT_VIEW_1_REF, NCLOC_KEY, 10);
@@ -163,7 +163,7 @@ public class ViewsMeasureComputersVisitorTest {
}

@Test
public void nothing_to_compute_when_no_project_view() {
void nothing_to_compute_when_no_project_view() {
treeRootHolder.setRoot(builder(VIEW, ROOT_REF)
.addChildren(
builder(SUBVIEW, VIEW_REF)
@@ -186,7 +186,7 @@ public class ViewsMeasureComputersVisitorTest {
}

@Test
public void nothing_to_compute_when_no_measure_computers() {
void nothing_to_compute_when_no_measure_computers() {
treeRootHolder.setRoot(TREE_WITH_SUB_VIEWS);

addRawMeasure(PROJECT_VIEW_1_REF, NCLOC_KEY, 10);

+ 9
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/period/PeriodHolderRule.java View File

@@ -20,13 +20,20 @@
package org.sonar.ce.task.projectanalysis.period;

import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class PeriodHolderRule implements TestRule, PeriodHolder {
public class PeriodHolderRule implements TestRule, PeriodHolder, AfterEachCallback {
private PeriodHolderImpl delegate = new PeriodHolderImpl();

@Override
public void afterEach(ExtensionContext extensionContext) {
clear();
}

@Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
@@ -65,4 +72,5 @@ public class PeriodHolderRule implements TestRule, PeriodHolder {
public Period getPeriod() {
return delegate.getPeriod();
}

}

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitygate/MutableQualityGateHolderRule.java View File

@@ -20,10 +20,12 @@
package org.sonar.ce.task.projectanalysis.qualitygate;

import java.util.Optional;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.server.qualitygate.EvaluatedQualityGate;

public class MutableQualityGateHolderRule extends ExternalResource implements MutableQualityGateHolder {
public class MutableQualityGateHolderRule extends ExternalResource implements MutableQualityGateHolder, AfterEachCallback {
private MutableQualityGateHolder delegate = new QualityGateHolderImpl();

@Override
@@ -54,4 +56,9 @@ public class MutableQualityGateHolderRule extends ExternalResource implements Mu
public void reset() {
this.delegate = new QualityGateHolderImpl();
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
reset();
}
}

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitygate/MutableQualityGateStatusHolderRule.java View File

@@ -20,9 +20,11 @@
package org.sonar.ce.task.projectanalysis.qualitygate;

import java.util.Map;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;

public class MutableQualityGateStatusHolderRule extends ExternalResource implements MutableQualityGateStatusHolder {
public class MutableQualityGateStatusHolderRule extends ExternalResource implements MutableQualityGateStatusHolder, AfterEachCallback {
private MutableQualityGateStatusHolder delegate = new QualityGateStatusHolderImpl();

@Override
@@ -48,4 +50,9 @@ public class MutableQualityGateStatusHolderRule extends ExternalResource impleme
public void reset() {
this.delegate = new QualityGateStatusHolderImpl();
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
reset();
}
}

+ 8
- 6
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitygate/QualityGateHolderRule.java View File

@@ -21,12 +21,14 @@ package org.sonar.ce.task.projectanalysis.qualitygate;

import java.util.Optional;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.server.qualitygate.EvaluatedQualityGate;

import static com.google.common.base.Preconditions.checkState;

public class QualityGateHolderRule extends ExternalResource implements QualityGateHolder {
public class QualityGateHolderRule implements QualityGateHolder, AfterEachCallback {
@Nullable
private Optional<QualityGate> qualityGate;
@Nullable
@@ -52,13 +54,13 @@ public class QualityGateHolderRule extends ExternalResource implements QualityGa
return evaluation;
}

@Override
protected void after() {
reset();
}

public void reset() {
this.qualityGate = null;
this.evaluation = null;
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
reset();
}
}

+ 37
- 36
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java View File

@@ -21,9 +21,9 @@ package org.sonar.ce.task.projectanalysis.qualitymodel;

import java.util.Arrays;
import java.util.Date;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.Duration;
import org.sonar.ce.task.projectanalysis.component.Component;
@@ -69,21 +69,21 @@ import static org.sonar.server.measure.Rating.C;
import static org.sonar.server.measure.Rating.D;
import static org.sonar.server.measure.Rating.E;

public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
class NewReliabilityAndSecurityRatingMeasuresVisitorTest {

private static final long LEAK_PERIOD_SNAPSHOT_IN_MILLISEC = 12323L;
private static final Date DEFAULT_ISSUE_CREATION_DATE = new Date(1000L);
private static final Date AFTER_LEAK_PERIOD_DATE = new Date(LEAK_PERIOD_SNAPSHOT_IN_MILLISEC + 5000L);

static final String LANGUAGE_KEY_1 = "lKey1";
private static final String LANGUAGE_KEY_1 = "lKey1";

static final int PROJECT_REF = 1;
static final int ROOT_DIR_REF = 12;
static final int DIRECTORY_REF = 123;
static final int FILE_1_REF = 1231;
static final int FILE_2_REF = 1232;
private static final int PROJECT_REF = 1;
private static final int ROOT_DIR_REF = 12;
private static final int DIRECTORY_REF = 123;
private static final int FILE_1_REF = 1231;
private static final int FILE_2_REF = 1232;

static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project")
private static final Component ROOT_PROJECT = builder(Component.Type.PROJECT, PROJECT_REF).setKey("project")
.addChildren(
builder(DIRECTORY, ROOT_DIR_REF).setKey("dir")
.addChildren(
@@ -95,33 +95,34 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
.build())
.build();

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@RegisterExtension
private final TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();

@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
@RegisterExtension
private final MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(NEW_SECURITY_RATING)
.add(NEW_RELIABILITY_RATING);

@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
@RegisterExtension
private final MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);

@Rule
public ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder);
@Rule
public FillComponentIssuesVisitorRule fillComponentIssuesVisitorRule = new FillComponentIssuesVisitorRule(componentIssuesRepositoryRule, treeRootHolder);
private final ComponentIssuesRepositoryRule componentIssuesRepositoryRule = new ComponentIssuesRepositoryRule(treeRootHolder);

@RegisterExtension
private final FillComponentIssuesVisitorRule fillComponentIssuesVisitorRule =
new FillComponentIssuesVisitorRule(componentIssuesRepositoryRule, treeRootHolder);

private final NewIssueClassifier newIssueClassifier = mock(NewIssueClassifier.class);
private final VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(fillComponentIssuesVisitorRule,
new NewReliabilityAndSecurityRatingMeasuresVisitor(metricRepository, measureRepository, componentIssuesRepositoryRule, newIssueClassifier)));

@Before
public void before() {
@BeforeEach
void before() {
when(newIssueClassifier.isEnabled()).thenReturn(true);
}

@Test
public void measures_created_for_project_are_all_A_when_they_have_no_FILE_child() {
void measures_created_for_project_are_all_A_when_they_have_no_FILE_child() {
ReportComponent root = builder(PROJECT, 1).build();
treeRootHolder.setRoot(root);

@@ -132,7 +133,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void no_measure_if_there_is_no_period() {
void no_measure_if_there_is_no_period() {
when(newIssueClassifier.isEnabled()).thenReturn(false);
treeRootHolder.setRoot(builder(PROJECT, 1).build());

@@ -142,7 +143,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_new_security_rating() {
void compute_new_security_rating() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newVulnerabilityIssue(10L, MAJOR),
@@ -166,7 +167,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_new_security_rating_to_A_when_no_issue() {
void compute_new_security_rating_to_A_when_no_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF);

@@ -180,7 +181,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_new_security_rating_to_A_when_no_new_issue() {
void compute_new_security_rating_to_A_when_no_new_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, oldVulnerabilityIssue(1L, MAJOR));

@@ -194,7 +195,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_new_reliability_rating() {
void compute_new_reliability_rating() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newBugIssue(10L, MAJOR),
@@ -219,7 +220,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_new_reliability_rating_to_A_when_no_issue() {
void compute_new_reliability_rating_to_A_when_no_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF);

@@ -233,7 +234,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_new_reliability_rating_to_A_when_no_new_issue() {
void compute_new_reliability_rating_to_A_when_no_new_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, oldBugIssue(1L, MAJOR));

@@ -247,7 +248,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_E_reliability_and_security_rating_on_blocker_issue() {
void compute_E_reliability_and_security_rating_on_blocker_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newBugIssue(10L, BLOCKER),
@@ -262,7 +263,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_D_reliability_and_security_rating_on_critical_issue() {
void compute_D_reliability_and_security_rating_on_critical_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newBugIssue(10L, CRITICAL),
@@ -277,7 +278,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_C_reliability_and_security_rating_on_major_issue() {
void compute_C_reliability_and_security_rating_on_major_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newBugIssue(10L, MAJOR),
@@ -292,7 +293,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_B_reliability_and_security_rating_on_minor_issue() {
void compute_B_reliability_and_security_rating_on_minor_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newBugIssue(10L, MINOR),
@@ -307,7 +308,7 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitorTest {
}

@Test
public void compute_A_reliability_and_security_rating_on_info_issue() {
void compute_A_reliability_and_security_rating_on_info_issue() {
treeRootHolder.setRoot(ROOT_PROJECT);
fillComponentIssuesVisitorRule.setIssues(FILE_1_REF,
newBugIssue(10L, INFO).setCreationDate(AFTER_LEAK_PERIOD_DATE),

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualityprofile/ActiveRulesHolderRule.java View File

@@ -22,10 +22,12 @@ package org.sonar.ce.task.projectanalysis.qualityprofile;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.api.rule.RuleKey;

public class ActiveRulesHolderRule extends ExternalResource implements ActiveRulesHolder {
public class ActiveRulesHolderRule extends ExternalResource implements ActiveRulesHolder, AfterEachCallback {

private final Map<RuleKey, ActiveRule> activeRulesByKey = new HashMap<>();

@@ -43,4 +45,9 @@ public class ActiveRulesHolderRule extends ExternalResource implements ActiveRul
protected void after() {
activeRulesByKey.clear();
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
after();
}
}

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepositoryRule.java View File

@@ -22,12 +22,14 @@ package org.sonar.ce.task.projectanalysis.scm;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.projectanalysis.component.Component;

import static com.google.common.base.Preconditions.checkNotNull;

public class ScmInfoRepositoryRule extends ExternalResource implements ScmInfoRepository {
public class ScmInfoRepositoryRule extends ExternalResource implements ScmInfoRepository, AfterEachCallback {

private Map<Integer, ScmInfo> scmInfoByFileRef = new HashMap<>();

@@ -52,4 +54,9 @@ public class ScmInfoRepositoryRule extends ExternalResource implements ScmInfoRe
scmInfoByFileRef.put(fileRef, new ScmInfoImpl(changesets.values().toArray(new Changeset[0])));
return this;
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
after();
}
}

+ 18
- 22
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceHashRepositoryImplTest.java View File

@@ -22,14 +22,12 @@ package org.sonar.ce.task.projectanalysis.source;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Arrays;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
@@ -43,38 +41,36 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(DataProviderRunner.class)
public class SourceHashRepositoryImplTest {
class SourceHashRepositoryImplTest {
private static final int FILE_REF = 112;
private static final String FILE_KEY = "file key";
private static final Component FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_REF).setKey(FILE_KEY).build();
private static final String[] SOME_LINES = {"line 1", "line after line 1", "line 4 minus 1", "line 100 by 10"};

@Rule
public SourceLinesRepositoryRule sourceLinesRepository = new SourceLinesRepositoryRule();
@RegisterExtension
private final SourceLinesRepositoryRule sourceLinesRepository = new SourceLinesRepositoryRule();

private SourceLinesRepository mockedSourceLinesRepository = mock(SourceLinesRepository.class);
private final SourceLinesRepository mockedSourceLinesRepository = mock(SourceLinesRepository.class);

private SourceHashRepositoryImpl underTest = new SourceHashRepositoryImpl(sourceLinesRepository);
private SourceHashRepositoryImpl mockedUnderTest = new SourceHashRepositoryImpl(mockedSourceLinesRepository);
private final SourceHashRepositoryImpl underTest = new SourceHashRepositoryImpl(sourceLinesRepository);
private final SourceHashRepositoryImpl mockedUnderTest = new SourceHashRepositoryImpl(mockedSourceLinesRepository);

@Test
public void getRawSourceHash_throws_NPE_if_Component_argument_is_null() {
void getRawSourceHash_throws_NPE_if_Component_argument_is_null() {
assertThatThrownBy(() -> underTest.getRawSourceHash(null))
.isInstanceOf(NullPointerException.class)
.hasMessage("Specified component can not be null");
}

@Test
@UseDataProvider("componentsOfAllTypesButFile")
public void getRawSourceHash_throws_IAE_if_Component_argument_is_not_FILE(Component component) {
@ParameterizedTest
@MethodSource("componentsOfAllTypesButFile")
void getRawSourceHash_throws_IAE_if_Component_argument_is_not_FILE(Component component) {
assertThatThrownBy(() -> underTest.getRawSourceHash(component))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("File source information can only be retrieved from FILE components (got " + component.getType() + ")");
}

@DataProvider
public static Object[][] componentsOfAllTypesButFile() {
private static Object[][] componentsOfAllTypesButFile() {
return FluentIterable.from(Arrays.asList(Component.Type.values()))
.filter(new Predicate<Component.Type>() {
@Override
@@ -108,7 +104,7 @@ public class SourceHashRepositoryImplTest {
}

@Test
public void getRawSourceHash_returns_hash_of_lines_from_SourceLinesRepository() {
void getRawSourceHash_returns_hash_of_lines_from_SourceLinesRepository() {
sourceLinesRepository.addLines(FILE_REF, SOME_LINES);

String rawSourceHash = underTest.getRawSourceHash(FILE_COMPONENT);
@@ -122,7 +118,7 @@ public class SourceHashRepositoryImplTest {
}

@Test
public void getRawSourceHash_reads_lines_from_SourceLinesRepository_only_the_first_time() {
void getRawSourceHash_reads_lines_from_SourceLinesRepository_only_the_first_time() {
when(mockedSourceLinesRepository.readLines(FILE_COMPONENT)).thenReturn(CloseableIterator.from(Arrays.asList(SOME_LINES).iterator()));

String rawSourceHash = mockedUnderTest.getRawSourceHash(FILE_COMPONENT);
@@ -133,7 +129,7 @@ public class SourceHashRepositoryImplTest {
}

@Test
public void getRawSourceHash_let_exception_go_through() {
void getRawSourceHash_let_exception_go_through() {
IllegalArgumentException thrown = new IllegalArgumentException("this IAE will cause the hash computation to fail");
when(mockedSourceLinesRepository.readLines(FILE_COMPONENT)).thenThrow(thrown);


+ 14
- 13
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImplTest.java View File

@@ -20,9 +20,9 @@
package org.sonar.ce.task.projectanalysis.source;

import java.util.Arrays;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.period.NewCodeReferenceBranchComponentUuids;
@@ -40,7 +40,7 @@ import static org.mockito.Mockito.when;
import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;

public class SourceLinesDiffImplTest {
class SourceLinesDiffImplTest {

private final DbClient dbClient = mock(DbClient.class);
private final DbSession dbSession = mock(DbSession.class);
@@ -50,11 +50,12 @@ public class SourceLinesDiffImplTest {
private final AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
private final ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class);
private final NewCodeReferenceBranchComponentUuids newCodeReferenceBranchComponentUuids = mock(NewCodeReferenceBranchComponentUuids.class);
@Rule
public PeriodHolderRule periodHolder = new PeriodHolderRule();

@Rule
public MutableMovedFilesRepositoryRule movedFiles = new MutableMovedFilesRepositoryRule();
@RegisterExtension
private final PeriodHolderRule periodHolder = new PeriodHolderRule();

@RegisterExtension
private final MutableMovedFilesRepositoryRule movedFiles = new MutableMovedFilesRepositoryRule();

private final SourceLinesDiffImpl underTest = new SourceLinesDiffImpl(dbClient, fileSourceDao, sourceLinesHash,
referenceBranchComponentUuids, movedFiles, analysisMetadataHolder, periodHolder, newCodeReferenceBranchComponentUuids);
@@ -71,15 +72,15 @@ public class SourceLinesDiffImplTest {
"}"
};

@Before
public void setUp() {
@BeforeEach
void setUp() {
when(dbClient.openSession(false)).thenReturn(dbSession);
when(dbClient.componentDao()).thenReturn(componentDao);
when(dbClient.fileSourceDao()).thenReturn(fileSourceDao);
}

@Test
public void should_find_diff_with_reference_branch_for_prs() {
void should_find_diff_with_reference_branch_for_prs() {
periodHolder.setPeriod(null);
Component component = fileComponent(FILE_REF);

@@ -93,7 +94,7 @@ public class SourceLinesDiffImplTest {
}

@Test
public void all_file_is_modified_if_no_source_in_db() {
void all_file_is_modified_if_no_source_in_db() {
periodHolder.setPeriod(null);
Component component = fileComponent(FILE_REF);

@@ -103,7 +104,7 @@ public class SourceLinesDiffImplTest {
}

@Test
public void should_find_no_diff_when_report_and_db_content_are_identical() {
void should_find_no_diff_when_report_and_db_content_are_identical() {
periodHolder.setPeriod(null);
Component component = fileComponent(FILE_REF);


+ 8
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesRepositoryRule.java View File

@@ -23,6 +23,8 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.Arrays;
import java.util.Collection;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.core.util.CloseableIterator;
@@ -30,10 +32,15 @@ import org.sonar.core.util.CloseableIterator;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

public class SourceLinesRepositoryRule extends ExternalResource implements SourceLinesRepository {
public class SourceLinesRepositoryRule extends ExternalResource implements SourceLinesRepository, AfterEachCallback {

private Multimap<Integer, String> lines = ArrayListMultimap.create();

@Override
public void afterEach(ExtensionContext context) {
after();
}

@Override
protected void after() {
lines.clear();

+ 10
- 10
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadQualityGateStepTest.java View File

@@ -20,9 +20,9 @@
package org.sonar.ce.task.projectanalysis.step;

import java.util.Arrays;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.metric.Metric;
import org.sonar.ce.task.projectanalysis.metric.MetricImpl;
@@ -37,9 +37,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class LoadQualityGateStepTest {
@Rule
public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();
class LoadQualityGateStepTest {
@RegisterExtension
private final MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();

private final AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
private final QualityGateServiceImpl qualityGateService = mock(QualityGateServiceImpl.class);
@@ -47,13 +47,13 @@ public class LoadQualityGateStepTest {
private final LoadQualityGateStep underTest = new LoadQualityGateStep(qualityGateService, mutableQualityGateHolder, analysisMetadataHolder);
private final Project project = mock(Project.class);

@Before
public void before() {
@BeforeEach
void before() {
when(analysisMetadataHolder.getProject()).thenReturn(project);
}

@Test
public void filter_conditions_on_pull_request() {
void filter_conditions_on_pull_request() {
Metric newMetric = new MetricImpl("1", "new_key", "name", Metric.MetricType.INT);
Metric metric = new MetricImpl("2", "key", "name", Metric.MetricType.INT);
Condition variation = new Condition(newMetric, Condition.Operator.GREATER_THAN.getDbValue(), "1.0");
@@ -69,7 +69,7 @@ public class LoadQualityGateStepTest {
}

@Test
public void execute_sets_effective_quality_gate() {
void execute_sets_effective_quality_gate() {
QualityGate qg = mock(QualityGate.class);
when(qualityGateService.findEffectiveQualityGate(project)).thenReturn(qg);


+ 11
- 11
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadQualityProfilesStepTest.java View File

@@ -20,8 +20,8 @@
package org.sonar.ce.task.projectanalysis.step;

import org.assertj.core.data.MapEntry;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
@@ -40,17 +40,17 @@ import static org.sonar.db.rule.RuleTesting.XOO_X2;

public class LoadQualityProfilesStepTest {

@Rule
public BatchReportReaderRule batchReportReader = new BatchReportReaderRule();
@RegisterExtension
private final BatchReportReaderRule batchReportReader = new BatchReportReaderRule();

@Rule
public RuleRepositoryRule ruleRepository = new RuleRepositoryRule();
@RegisterExtension
private final RuleRepositoryRule ruleRepository = new RuleRepositoryRule();

private ActiveRulesHolderImpl activeRulesHolder = new ActiveRulesHolderImpl();
private LoadQualityProfilesStep underTest = new LoadQualityProfilesStep(batchReportReader, activeRulesHolder, ruleRepository);
private final ActiveRulesHolderImpl activeRulesHolder = new ActiveRulesHolderImpl();
private final LoadQualityProfilesStep underTest = new LoadQualityProfilesStep(batchReportReader, activeRulesHolder, ruleRepository);

@Test
public void feed_active_rules() {
void feed_active_rules() {
ruleRepository.add(XOO_X1)
.setPluginKey("xoo");
ruleRepository.add(XOO_X2)
@@ -86,7 +86,7 @@ public class LoadQualityProfilesStepTest {
}

@Test
public void ignore_rules_with_status_REMOVED() {
void ignore_rules_with_status_REMOVED() {
ruleRepository.add(new DumbRule(XOO_X1).setStatus(RuleStatus.REMOVED));

ScannerReport.ActiveRule.Builder batch1 = ScannerReport.ActiveRule.newBuilder()
@@ -100,7 +100,7 @@ public class LoadQualityProfilesStepTest {
}

@Test
public void ignore_not_found_rules() {
void ignore_not_found_rules() {
ScannerReport.ActiveRule.Builder batch1 = ScannerReport.ActiveRule.newBuilder()
.setRuleRepository(XOO_X1.repository()).setRuleKey(XOO_X1.rule())
.setSeverity(Constants.Severity.BLOCKER);

+ 32
- 30
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/QualityGateMeasuresStepTest.java View File

@@ -25,9 +25,9 @@ import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.assertj.core.api.AbstractAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.config.internal.ConfigurationBridge;
@@ -57,6 +57,7 @@ import org.sonar.ce.task.step.TestComputationStepContext;

import static com.google.common.collect.ImmutableList.of;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -66,7 +67,7 @@ import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.ERROR;
import static org.sonar.ce.task.projectanalysis.measure.Measure.Level.OK;
import static org.sonar.ce.task.projectanalysis.measure.MeasureAssert.assertThat;

public class QualityGateMeasuresStepTest {
class QualityGateMeasuresStepTest {
private static final MetricImpl INT_METRIC_1 = createIntMetric(1);
private static final String INT_METRIC_1_KEY = INT_METRIC_1.getKey();
private static final MetricImpl INT_METRIC_2 = createIntMetric(2);
@@ -77,24 +78,25 @@ public class QualityGateMeasuresStepTest {
private static final String SOME_QG_UUID = "7521551";
private static final String SOME_QG_NAME = "name";

@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@Rule
public QualityGateHolderRule qualityGateHolder = new QualityGateHolderRule();
@Rule
public MutableQualityGateStatusHolderRule qualityGateStatusHolder = new MutableQualityGateStatusHolderRule();
@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule();
@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
private EvaluationResultTextConverter resultTextConverter = mock(EvaluationResultTextConverter.class);
private MapSettings mapSettings = new MapSettings();
private TestSettingsRepository settings = new TestSettingsRepository(new ConfigurationBridge(mapSettings));
private QualityGateMeasuresStep underTest = new QualityGateMeasuresStep(treeRootHolder, qualityGateHolder, qualityGateStatusHolder, measureRepository, metricRepository,
@RegisterExtension
private final TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@RegisterExtension
private final QualityGateHolderRule qualityGateHolder = new QualityGateHolderRule();
@RegisterExtension
private final MutableQualityGateStatusHolderRule qualityGateStatusHolder = new MutableQualityGateStatusHolderRule();
@RegisterExtension
private final MetricRepositoryRule metricRepository = new MetricRepositoryRule();
@RegisterExtension
private final MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);

private final EvaluationResultTextConverter resultTextConverter = mock(EvaluationResultTextConverter.class);
private final MapSettings mapSettings = new MapSettings();
private final TestSettingsRepository settings = new TestSettingsRepository(new ConfigurationBridge(mapSettings));
private final QualityGateMeasuresStep underTest = new QualityGateMeasuresStep(treeRootHolder, qualityGateHolder, qualityGateStatusHolder, measureRepository, metricRepository,
resultTextConverter, new SmallChangesetQualityGateSpecialCase(measureRepository, metricRepository, settings));

@Before
public void setUp() {
@BeforeEach
void setUp() {
metricRepository
.add(CoreMetrics.ALERT_STATUS)
.add(CoreMetrics.QUALITY_GATE_DETAILS)
@@ -118,27 +120,27 @@ public class QualityGateMeasuresStepTest {
}

@Test
public void no_measure_if_tree_has_no_project() {
void no_measure_if_tree_has_no_project() {
ReportComponent notAProjectComponent = ReportComponent.builder(Component.Type.DIRECTORY, 1).build();

treeRootHolder.setRoot(notAProjectComponent);

underTest.execute(new TestComputationStepContext());

measureRepository.getAddedRawMeasures(1).isEmpty();
assertTrue(measureRepository.getAddedRawMeasures(1).isEmpty());
}

@Test
public void no_measure_if_there_is_no_qualitygate() {
void no_measure_if_there_is_no_qualitygate() {
qualityGateHolder.setQualityGate(null);

underTest.execute(new TestComputationStepContext());

measureRepository.getAddedRawMeasures(PROJECT_COMPONENT).isEmpty();
assertTrue(measureRepository.getAddedRawMeasures(PROJECT_COMPONENT).isEmpty());
}

@Test
public void mutableQualityGateStatusHolder_is_not_populated_if_there_is_no_qualitygate() {
void mutableQualityGateStatusHolder_is_not_populated_if_there_is_no_qualitygate() {
qualityGateHolder.setQualityGate(null);

underTest.execute(new TestComputationStepContext());
@@ -149,7 +151,7 @@ public class QualityGateMeasuresStepTest {
}

@Test
public void new_measures_are_created_even_if_there_is_no_rawMeasure_for_metric_of_condition() {
void new_measures_are_created_even_if_there_is_no_rawMeasure_for_metric_of_condition() {
Condition equals2Condition = createLessThanCondition(INT_METRIC_1, "2");
qualityGateHolder.setQualityGate(new QualityGate(SOME_QG_UUID, SOME_QG_NAME, of(equals2Condition)));

@@ -171,7 +173,7 @@ public class QualityGateMeasuresStepTest {
}

@Test
public void rawMeasure_is_updated_if_present_and_new_measures_are_created_if_project_has_measure_for_metric_of_condition() {
void rawMeasure_is_updated_if_present_and_new_measures_are_created_if_project_has_measure_for_metric_of_condition() {
int rawValue = 3;
Condition equals2Condition = createLessThanCondition(INT_METRIC_1, "2");
Measure rawMeasure = newMeasureBuilder().create(rawValue, null);
@@ -199,7 +201,7 @@ public class QualityGateMeasuresStepTest {
}

@Test
public void new_measures_have_ERROR_level_if_at_least_one_updated_measure_has_ERROR_level() {
void new_measures_have_ERROR_level_if_at_least_one_updated_measure_has_ERROR_level() {
int rawValue = 3;
Condition equalsOneErrorCondition = createLessThanCondition(INT_METRIC_1, "4");
Condition equalsOneOkCondition = createLessThanCondition(INT_METRIC_2, "2");
@@ -237,7 +239,7 @@ public class QualityGateMeasuresStepTest {
}

@Test
public void new_measure_has_ERROR_level_of_all_conditions_for_a_specific_metric_if_its_the_worst() {
void new_measure_has_ERROR_level_of_all_conditions_for_a_specific_metric_if_its_the_worst() {
int rawValue = 3;
Condition fixedCondition = createLessThanCondition(INT_METRIC_1, "4");
Condition periodCondition = createLessThanCondition(INT_METRIC_1, "2");
@@ -255,7 +257,7 @@ public class QualityGateMeasuresStepTest {
}

@Test
public void new_measure_has_condition_on_leak_period_when_all_conditions_on_specific_metric_has_same_QG_level() {
void new_measure_has_condition_on_leak_period_when_all_conditions_on_specific_metric_has_same_QG_level() {
int rawValue = 0;
Condition fixedCondition = createLessThanCondition(INT_METRIC_1, "1");
Condition periodCondition = createLessThanCondition(INT_METRIC_1, "1");

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java View File

@@ -24,6 +24,8 @@ import java.util.Map;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.util.InitializedProperty;
import org.sonar.db.component.BranchType;
@@ -34,7 +36,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.apache.commons.lang.StringUtils.defaultIfBlank;

public class AnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder {
public class AnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder, AfterEachCallback {

private final InitializedProperty<String> uuid = new InitializedProperty<>();
private final InitializedProperty<Long> analysisDate = new InitializedProperty<>();
@@ -228,4 +230,9 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta
Branch property = this.branch.getProperty();
return property != null && property.getType() == BranchType.PULL_REQUEST;
}

@Override
public void afterEach(ExtensionContext context) {
after();
}
}

+ 9
- 1
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java View File

@@ -23,6 +23,8 @@ import java.util.Map;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.core.platform.PlatformEditionProvider;
import org.sonar.server.project.Project;
@@ -30,7 +32,7 @@ import org.sonar.server.qualityprofile.QualityProfile;

import static org.mockito.Mockito.mock;

public class MutableAnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder {
public class MutableAnalysisMetadataHolderRule extends ExternalResource implements MutableAnalysisMetadataHolder, AfterEachCallback {

private final PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
private AnalysisMetadataHolderImpl delegate = new AnalysisMetadataHolderImpl(editionProvider);
@@ -188,4 +190,10 @@ public class MutableAnalysisMetadataHolderRule extends ExternalResource implemen
public boolean isPullRequest() {
return delegate.isPullRequest();
}

@Override
public void afterEach(ExtensionContext extensionContext) {
after();
}

}

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/component/TreeRootHolderRule.java View File

@@ -23,13 +23,15 @@ import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.Optional;
import javax.annotation.CheckForNull;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;

public class TreeRootHolderRule extends ExternalResource implements TreeRootHolder {
public class TreeRootHolderRule extends ExternalResource implements TreeRootHolder, AfterEachCallback {
protected TreeRootHolderImpl delegate = new TreeRootHolderImpl();

@CheckForNull
@@ -40,6 +42,11 @@ public class TreeRootHolderRule extends ExternalResource implements TreeRootHold
this.delegate = null;
}

@Override
public void afterEach(ExtensionContext context) throws Exception {
after();
}

public TreeRootHolderRule setRoot(Component root) {
return setRoots(root, root);
}

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/measure/MeasureRepositoryRule.java View File

@@ -28,6 +28,8 @@ import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ComponentProvider;
@@ -49,7 +51,7 @@ import static java.util.Objects.requireNonNull;
* methods that takes component ref and metric keys thanks to the integration with various Component and Metric
* providers.
*/
public class MeasureRepositoryRule extends ExternalResource implements MeasureRepository {
public class MeasureRepositoryRule extends ExternalResource implements MeasureRepository, AfterEachCallback {
private final ComponentProvider componentProvider;
@CheckForNull
private final MetricRepositoryRule metricRepositoryRule;
@@ -208,6 +210,11 @@ public class MeasureRepositoryRule extends ExternalResource implements MeasureRe
return rawMeasures.isEmpty();
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
after();
}

private static final class InternalKey {
private final String componentRef;
private final String metricKey;

+ 8
- 1
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/metric/MetricRepositoryRule.java View File

@@ -23,13 +23,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;

import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;

public class MetricRepositoryRule extends ExternalResource implements MetricRepository {
public class MetricRepositoryRule extends ExternalResource implements MetricRepository, AfterEachCallback {
private final Map<String, Metric> metricsByKey = new HashMap<>();
private final Map<String, Metric> metricsByUuid = new HashMap<>();

@@ -118,4 +120,9 @@ public class MetricRepositoryRule extends ExternalResource implements MetricRepo
public List<Metric> getMetricsByType(Metric.MetricType type) {
return metricsByKey.values().stream().filter(m -> m.getType() == type).toList();
}

@Override
public void afterEach(ExtensionContext context) throws Exception {
after();
}
}

server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/BranchFeatureRule.java → server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/step/BaseStepJUnit5Test.java View File

@@ -17,31 +17,24 @@
* 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.server.ui.ws;
package org.sonar.ce.task.projectanalysis.step;

import org.junit.rules.ExternalResource;
import org.sonar.server.branch.BranchFeatureProxy;
import org.junit.jupiter.api.Test;
import org.sonar.ce.task.step.ComputationStep;

public class BranchFeatureRule extends ExternalResource implements BranchFeatureProxy {
import static org.assertj.core.api.Assertions.assertThat;

private boolean enabled;

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

@Override
protected void after() {
reset();
}
/**
* Temporary solution to test metadata. Should be replaced by a medium test of
* all computation stack
*/
public abstract class BaseStepJUnit5Test {

public void reset() {
this.enabled = false;
}
protected abstract ComputationStep step();

@Override
public boolean isEnabled() {
return enabled;
@Test
public void test_metadata() {
assertThat(step().toString()).isNotEmpty();
assertThat(step().getDescription()).isNotEmpty();
}

}

+ 69
- 68
server/sonar-ce/src/it/java/org/sonar/ce/taskprocessor/CeWorkerImplIT.java View File

@@ -30,16 +30,16 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.stubbing.Answer;
import org.slf4j.event.Level;
import org.sonar.api.impl.utils.TestSystem2;
import org.sonar.api.testfixtures.log.LogAndArguments;
import org.sonar.api.testfixtures.log.LogTester;
import org.sonar.api.testfixtures.log.LogTesterJUnit5;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LoggerLevel;
@@ -76,54 +76,55 @@ import static org.sonar.ce.taskprocessor.CeWorker.Result.DISABLED;
import static org.sonar.ce.taskprocessor.CeWorker.Result.NO_TASK;
import static org.sonar.ce.taskprocessor.CeWorker.Result.TASK_PROCESSED;

public class CeWorkerImplIT {
class CeWorkerImplIT {

private System2 system2 = new TestSystem2().setNow(1_450_000_000_000L);

@Rule
public CeTaskProcessorRepositoryRule taskProcessorRepository = new CeTaskProcessorRepositoryRule();
@Rule
public LogTester logTester = new LogTester();
@Rule
public DbTester db = DbTester.create(system2);

private DbSession session = db.getSession();

private InternalCeQueue queue = mock(InternalCeQueue.class);
private ReportTaskProcessor taskProcessor = mock(ReportTaskProcessor.class);
private CeWorker.ExecutionListener executionListener1 = mock(CeWorker.ExecutionListener.class);
private CeWorker.ExecutionListener executionListener2 = mock(CeWorker.ExecutionListener.class);
private CeWorkerController ceWorkerController = mock(CeWorkerController.class);
private ArgumentCaptor<String> workerUuidCaptor = ArgumentCaptor.forClass(String.class);
private int randomOrdinal = new Random().nextInt(50);
private String workerUuid = UUID.randomUUID().toString();
private CeWorker underTest = new CeWorkerImpl(randomOrdinal, workerUuid, queue, taskProcessorRepository, ceWorkerController,
executionListener1, executionListener2);
private CeWorker underTestNoListener = new CeWorkerImpl(randomOrdinal, workerUuid, queue, taskProcessorRepository, ceWorkerController);
private InOrder inOrder = inOrder(taskProcessor, queue, executionListener1, executionListener2);
@RegisterExtension
private final CeTaskProcessorRepositoryRule taskProcessorRepository = new CeTaskProcessorRepositoryRule();
@RegisterExtension
private final LogTesterJUnit5 logTester = new LogTesterJUnit5();
@RegisterExtension
private final DbTester db = DbTester.create(system2);

private final DbSession session = db.getSession();

private final InternalCeQueue queue = mock(InternalCeQueue.class);
private final ReportTaskProcessor taskProcessor = mock(ReportTaskProcessor.class);
private final CeWorker.ExecutionListener executionListener1 = mock(CeWorker.ExecutionListener.class);
private final CeWorker.ExecutionListener executionListener2 = mock(CeWorker.ExecutionListener.class);
private final CeWorkerController ceWorkerController = mock(CeWorkerController.class);
private final ArgumentCaptor<String> workerUuidCaptor = ArgumentCaptor.forClass(String.class);
private final int ordinal = 37;
private final String workerUuid = "8e5cc1dd-4617-4974-9234-0a9539212615";
private final CeWorker underTest = new CeWorkerImpl(ordinal, workerUuid, queue, taskProcessorRepository,
ceWorkerController, executionListener1, executionListener2);
private final CeWorker underTestNoListener = new CeWorkerImpl(ordinal, workerUuid, queue, taskProcessorRepository,
ceWorkerController);
private final InOrder inOrder = inOrder(taskProcessor, queue, executionListener1, executionListener2);
private final CeTask.User submitter = new CeTask.User("UUID_USER_1", "LOGIN_1");

@Before
public void setUp() {
@BeforeEach
void setUp() {
when(ceWorkerController.isEnabled(any(CeWorker.class))).thenReturn(true);
}

@Test
public void constructor_throws_IAE_if_ordinal_is_less_than_zero() {
void constructor_throws_IAE_if_ordinal_is_less_than_zero() {
assertThatThrownBy(() -> new CeWorkerImpl(-1 - new Random().nextInt(20), workerUuid, queue, taskProcessorRepository, ceWorkerController))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Ordinal must be >= 0");
}

@Test
public void getUUID_must_return_the_uuid_of_constructor() {
void getUUID_must_return_the_uuid_of_constructor() {
String uuid = UUID.randomUUID().toString();
CeWorker underTest = new CeWorkerImpl(randomOrdinal, uuid, queue, taskProcessorRepository, ceWorkerController);
CeWorker underTest = new CeWorkerImpl(ordinal, uuid, queue, taskProcessorRepository, ceWorkerController);
assertThat(underTest.getUUID()).isEqualTo(uuid);
}

@Test
public void worker_disabled() throws Exception {
void worker_disabled() throws Exception {
reset(ceWorkerController);
when(ceWorkerController.isEnabled(underTest)).thenReturn(false);

@@ -133,7 +134,7 @@ public class CeWorkerImplIT {
}

@Test
public void worker_disabled_no_listener() throws Exception {
void worker_disabled_no_listener() throws Exception {
reset(ceWorkerController);
when(ceWorkerController.isEnabled(underTest)).thenReturn(false);

@@ -143,7 +144,7 @@ public class CeWorkerImplIT {
}

@Test
public void no_pending_tasks_in_queue() throws Exception {
void no_pending_tasks_in_queue() throws Exception {
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.empty());

assertThat(underTest.call()).isEqualTo(NO_TASK);
@@ -152,7 +153,7 @@ public class CeWorkerImplIT {
}

@Test
public void no_pending_tasks_in_queue_without_listener() throws Exception {
void no_pending_tasks_in_queue_without_listener() throws Exception {
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.empty());

assertThat(underTestNoListener.call()).isEqualTo(NO_TASK);
@@ -161,7 +162,7 @@ public class CeWorkerImplIT {
}

@Test
public void fail_when_no_CeTaskProcessor_is_found_in_repository() throws Exception {
void fail_when_no_CeTaskProcessor_is_found_in_repository() throws Exception {
CeTask task = createCeTask(null);
taskProcessorRepository.setNoProcessorForTask(CeTaskTypes.REPORT);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(task));
@@ -177,7 +178,7 @@ public class CeWorkerImplIT {
}

@Test
public void fail_when_no_CeTaskProcessor_is_found_in_repository_without_listener() throws Exception {
void fail_when_no_CeTaskProcessor_is_found_in_repository_without_listener() throws Exception {
CeTask task = createCeTask(null);
taskProcessorRepository.setNoProcessorForTask(CeTaskTypes.REPORT);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(task));
@@ -190,7 +191,7 @@ public class CeWorkerImplIT {
}

@Test
public void peek_and_process_task() throws Exception {
void peek_and_process_task() throws Exception {
CeTask task = createCeTask(null);
taskProcessorRepository.setProcessorForTask(task.getType(), taskProcessor);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(task));
@@ -207,7 +208,7 @@ public class CeWorkerImplIT {
}

@Test
public void peek_and_process_task_without_listeners() throws Exception {
void peek_and_process_task_without_listeners() throws Exception {
CeTask task = createCeTask(null);
taskProcessorRepository.setProcessorForTask(task.getType(), taskProcessor);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(task));
@@ -221,7 +222,7 @@ public class CeWorkerImplIT {
}

@Test
public void fail_to_process_task() throws Exception {
void fail_to_process_task() throws Exception {
CeTask task = createCeTask(null);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(task));
taskProcessorRepository.setProcessorForTask(task.getType(), taskProcessor);
@@ -239,7 +240,7 @@ public class CeWorkerImplIT {
}

@Test
public void fail_to_process_task_without_listeners() throws Exception {
void fail_to_process_task_without_listeners() throws Exception {
CeTask task = createCeTask(null);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(task));
taskProcessorRepository.setProcessorForTask(task.getType(), taskProcessor);
@@ -254,7 +255,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_task_characteristics() throws Exception {
void log_task_characteristics() throws Exception {
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(createCeTask(null, "pullRequest", "123", "branch", "foo")));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);

@@ -269,7 +270,7 @@ public class CeWorkerImplIT {
}

@Test
public void do_not_log_submitter_param_if_anonymous_and_success() throws Exception {
void do_not_log_submitter_param_if_anonymous_and_success() throws Exception {
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(createCeTask(null)));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);

@@ -284,7 +285,7 @@ public class CeWorkerImplIT {
}

@Test
public void do_not_log_submitter_param_if_anonymous_and_error() throws Exception {
void do_not_log_submitter_param_if_anonymous_and_error() throws Exception {
CeTask ceTask = createCeTask(null);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
taskProcessorRepository.setProcessorForTask(ceTask.getType(), taskProcessor);
@@ -304,7 +305,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_submitter_login_if_authenticated_and_success() throws Exception {
void log_submitter_login_if_authenticated_and_success() throws Exception {
UserDto userDto = insertRandomUser();
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(createCeTask(toTaskSubmitter(userDto))));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -321,7 +322,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_submitterUuid_if_user_matching_submitterUuid_can_not_be_found() throws Exception {
void log_submitterUuid_if_user_matching_submitterUuid_can_not_be_found() throws Exception {
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(createCeTask(new CeTask.User("UUID_USER", null))));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);

@@ -337,7 +338,7 @@ public class CeWorkerImplIT {
}

@Test
public void display_submitterLogin_in_logs_when_set_in_case_of_error() throws Exception {
void display_submitterLogin_in_logs_when_set_in_case_of_error() throws Exception {
UserDto userDto = insertRandomUser();
CeTask ceTask = createCeTask(toTaskSubmitter(userDto));
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
@@ -357,7 +358,7 @@ public class CeWorkerImplIT {
}

@Test
public void display_start_stop_at_debug_level_for_console_if_DEBUG_is_enabled_and_task_successful() throws Exception {
void display_start_stop_at_debug_level_for_console_if_DEBUG_is_enabled_and_task_successful() throws Exception {
logTester.setLevel(LoggerLevel.DEBUG);

when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(createCeTask(submitter)));
@@ -375,7 +376,7 @@ public class CeWorkerImplIT {
}

@Test
public void display_start_at_debug_level_stop_at_error_level_for_console_if_DEBUG_is_enabled_and_task_failed() throws Exception {
void display_start_at_debug_level_stop_at_error_level_for_console_if_DEBUG_is_enabled_and_task_failed() throws Exception {
logTester.setLevel(LoggerLevel.DEBUG);

CeTask ceTask = createCeTask(submitter);
@@ -397,11 +398,11 @@ public class CeWorkerImplIT {
}

@Test
public void call_sets_and_restores_thread_name_with_information_of_worker_when_there_is_no_task_to_process() throws Exception {
void call_sets_and_restores_thread_name_with_information_of_worker_when_there_is_no_task_to_process() throws Exception {
String threadName = randomAlphabetic(3);
when(queue.peek(anyString(), anyBoolean())).thenAnswer(invocation -> {
assertThat(Thread.currentThread().getName())
.isEqualTo("Worker " + randomOrdinal + " (UUID=" + workerUuid + ") on " + threadName);
.isEqualTo("Worker " + ordinal + " (UUID=" + workerUuid + ") on " + threadName);
return Optional.empty();
});
Thread newThread = createThreadNameVerifyingThread(threadName);
@@ -411,11 +412,11 @@ public class CeWorkerImplIT {
}

@Test
public void call_sets_and_restores_thread_name_with_information_of_worker_when_a_task_is_processed() throws Exception {
void call_sets_and_restores_thread_name_with_information_of_worker_when_a_task_is_processed() throws Exception {
String threadName = randomAlphabetic(3);
when(queue.peek(anyString(), anyBoolean())).thenAnswer(invocation -> {
assertThat(Thread.currentThread().getName())
.isEqualTo("Worker " + randomOrdinal + " (UUID=" + workerUuid + ") on " + threadName);
.isEqualTo("Worker " + ordinal + " (UUID=" + workerUuid + ") on " + threadName);
return Optional.of(createCeTask(submitter));
});
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -426,12 +427,12 @@ public class CeWorkerImplIT {
}

@Test
public void call_sets_and_restores_thread_name_with_information_of_worker_when_an_error_occurs() throws Exception {
void call_sets_and_restores_thread_name_with_information_of_worker_when_an_error_occurs() throws Exception {
String threadName = randomAlphabetic(3);
CeTask ceTask = createCeTask(submitter);
when(queue.peek(anyString(), anyBoolean())).thenAnswer(invocation -> {
assertThat(Thread.currentThread().getName())
.isEqualTo("Worker " + randomOrdinal + " (UUID=" + workerUuid + ") on " + threadName);
.isEqualTo("Worker " + ordinal + " (UUID=" + workerUuid + ") on " + threadName);
return Optional.of(ceTask);
});
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -443,7 +444,7 @@ public class CeWorkerImplIT {
}

@Test
public void call_sets_and_restores_thread_name_with_information_of_worker_when_worker_is_disabled() throws Exception {
void call_sets_and_restores_thread_name_with_information_of_worker_when_worker_is_disabled() throws Exception {
reset(ceWorkerController);
when(ceWorkerController.isEnabled(underTest)).thenReturn(false);

@@ -455,7 +456,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_error_when_task_fails_with_not_MessageException() throws Exception {
void log_error_when_task_fails_with_not_MessageException() throws Exception {
CeTask ceTask = createCeTask(submitter);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -473,7 +474,7 @@ public class CeWorkerImplIT {
}

@Test
public void do_no_log_error_when_task_fails_with_MessageException() throws Exception {
void do_no_log_error_when_task_fails_with_MessageException() throws Exception {
CeTask ceTask = createCeTask(submitter);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -489,7 +490,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_error_when_task_was_successful_but_ending_state_can_not_be_persisted_to_db() throws Exception {
void log_error_when_task_was_successful_but_ending_state_can_not_be_persisted_to_db() throws Exception {
CeTask ceTask = createCeTask(submitter);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -501,7 +502,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_error_when_task_failed_and_ending_state_can_not_be_persisted_to_db() throws Exception {
void log_error_when_task_failed_and_ending_state_can_not_be_persisted_to_db() throws Exception {
CeTask ceTask = createCeTask(submitter);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -526,7 +527,7 @@ public class CeWorkerImplIT {
}

@Test
public void log_error_as_suppressed_when_task_failed_with_MessageException_and_ending_state_can_not_be_persisted_to_db() throws Exception {
void log_error_as_suppressed_when_task_failed_with_MessageException_and_ending_state_can_not_be_persisted_to_db() throws Exception {
CeTask ceTask = createCeTask(submitter);
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.of(ceTask));
taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
@@ -546,13 +547,13 @@ public class CeWorkerImplIT {
}

@Test
public void isExecutedBy_returns_false_when_no_interaction_with_instance() {
void isExecutedBy_returns_false_when_no_interaction_with_instance() {
assertThat(underTest.isExecutedBy(Thread.currentThread())).isFalse();
assertThat(underTest.isExecutedBy(new Thread())).isFalse();
}

@Test
public void isExecutedBy_returns_false_unless_a_thread_is_currently_calling_call() throws InterruptedException {
void isExecutedBy_returns_false_unless_a_thread_is_currently_calling_call() throws InterruptedException {
CountDownLatch inCallLatch = new CountDownLatch(1);
CountDownLatch assertionsDoneLatch = new CountDownLatch(1);
// mock long running peek(String) call => Thread is executing call() but not running a task
@@ -585,7 +586,7 @@ public class CeWorkerImplIT {
}

@Test
public void isExecutedBy_returns_false_unless_a_thread_is_currently_executing_a_task() throws InterruptedException {
void isExecutedBy_returns_false_unless_a_thread_is_currently_executing_a_task() throws InterruptedException {
CountDownLatch inCallLatch = new CountDownLatch(1);
CountDownLatch assertionsDoneLatch = new CountDownLatch(1);
String taskType = randomAlphabetic(12);
@@ -625,12 +626,12 @@ public class CeWorkerImplIT {
}

@Test
public void getCurrentTask_returns_empty_when_no_interaction_with_instance() {
void getCurrentTask_returns_empty_when_no_interaction_with_instance() {
assertThat(underTest.getCurrentTask()).isEmpty();
}

@Test
public void do_not_exclude_portfolio_when_indexation_task_lookup_is_disabled() throws Exception {
void do_not_exclude_portfolio_when_indexation_task_lookup_is_disabled() throws Exception {
// first call with empty queue to disable indexationTaskLookupEnabled
when(queue.peek(anyString(), anyBoolean())).thenReturn(Optional.empty());
assertThat(underTest.call()).isEqualTo(NO_TASK);
@@ -642,7 +643,7 @@ public class CeWorkerImplIT {
}

@Test
public void getCurrentTask_returns_empty_when_a_thread_is_currently_calling_call_but_not_executing_a_task() throws InterruptedException {
void getCurrentTask_returns_empty_when_a_thread_is_currently_calling_call_but_not_executing_a_task() throws InterruptedException {
CountDownLatch inCallLatch = new CountDownLatch(1);
CountDownLatch assertionsDoneLatch = new CountDownLatch(1);
// mock long running peek(String) call => Thread is executing call() but not running a task
@@ -671,7 +672,7 @@ public class CeWorkerImplIT {
}

@Test
public void getCurrentTask_returns_empty_unless_a_thread_is_currently_executing_a_task() throws InterruptedException {
void getCurrentTask_returns_empty_unless_a_thread_is_currently_executing_a_task() throws InterruptedException {
CountDownLatch inCallLatch = new CountDownLatch(1);
CountDownLatch assertionsDoneLatch = new CountDownLatch(1);
String taskType = randomAlphabetic(12);

+ 1
- 1
server/sonar-ce/src/test/java/org/sonar/ce/configuration/CeConfigurationRule.java View File

@@ -26,7 +26,7 @@ import static com.google.common.base.Preconditions.checkArgument;
/**
* Mutable implementation of {@link CeConfiguration} as {@link org.junit.Rule}.
*/
public class CeConfigurationRule extends ExternalResource implements CeConfiguration {
public class CeConfigurationRule implements CeConfiguration {
private int workerThreadCount = 1;
private int workerCount = 1;
private long queuePollingDelay = 2 * 1000L;

+ 1
- 1
server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeProcessingSchedulerImplTest.java View File

@@ -70,7 +70,7 @@ public class CeProcessingSchedulerImplTest {
// due to risks of infinite chaining of tasks/futures, a timeout is required for safety
@Rule
public TestRule safeguardTimeout = new DisableOnDebug(Timeout.seconds(60));
@Rule
public CeConfigurationRule ceConfiguration = new CeConfigurationRule();
private CeWorker ceWorker = mock(CeWorker.class);
private CeWorkerFactory ceWorkerFactory = new TestCeWorkerFactory(ceWorker);

+ 9
- 1
server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeTaskProcessorRepositoryRule.java View File

@@ -23,6 +23,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.ce.task.CeTask;
import org.sonar.ce.task.CeTaskResult;
@@ -35,10 +37,16 @@ import static java.util.Objects.requireNonNull;
* A {@link org.junit.Rule} that implements the {@link CeTaskProcessorRepository} interface and
* requires consumer to explicitly define if a specific Task type has an associated {@link CeTaskProcessor} or not.
*/
public class CeTaskProcessorRepositoryRule extends ExternalResource implements CeTaskProcessorRepository {
public class CeTaskProcessorRepositoryRule extends ExternalResource
implements CeTaskProcessorRepository, AfterEachCallback {

private final Map<String, CeTaskProcessor> index = new HashMap<>();

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
after();
}

@Override
protected void after() {
index.clear();

+ 0
- 1
server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeWorkerControllerImplTest.java View File

@@ -37,7 +37,6 @@ public class CeWorkerControllerImplTest {
/** 1 <= workerCount <= 5 */
private int randomWorkerCount = 1 + random.nextInt(5);

@Rule
public CeConfigurationRule ceConfigurationRule = new CeConfigurationRule()
.setWorkerCount(randomWorkerCount);
@Rule

+ 9
- 0
server/sonar-process/build.gradle View File

@@ -29,7 +29,16 @@ dependencies {
testImplementation 'junit:junit'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.hamcrest:hamcrest-core'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.awaitility:awaitility'
testImplementation project(':sonar-testing-harness')

testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
}

test {
// Enabling the JUnit Platform (see https://github.com/junit-team/junit5-samples/tree/master/junit5-migration-gradle)
useJUnitPlatform()
}

+ 16
- 2
server/sonar-process/src/test/java/org/sonar/process/LoggingRule.java View File

@@ -23,12 +23,15 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.joran.spi.JoranException;
import java.util.List;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import org.sonar.process.logging.LogbackHelper;

public class LoggingRule extends ExternalResource {
public class LoggingRule extends ExternalResource implements BeforeEachCallback, AfterEachCallback {

private final Class loggerClass;

@@ -37,12 +40,22 @@ public class LoggingRule extends ExternalResource {
}

@Override
protected void before() throws Throwable {
public void beforeEach(ExtensionContext extensionContext) throws Exception {
before();
}

@Override
protected void before() throws Exception {
new LogbackHelper().resetFromXml("/org/sonar/process/logback-test.xml");
TestLogbackAppender.events.clear();
setLevel(Level.INFO);
}

@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
after();
}

@Override
protected void after() {
TestLogbackAppender.events.clear();
@@ -88,4 +101,5 @@ public class LoggingRule extends ExternalResource {
.filter(e -> e.getLoggerName().equals(loggerClass.getName()))
.anyMatch(e -> e.getFormattedMessage().equals(message));
}

}

+ 10
- 9
server/sonar-process/src/test/java/org/sonar/process/cluster/health/HealthStateRefresherTest.java View File

@@ -22,8 +22,8 @@ package org.sonar.process.cluster.health;
import com.hazelcast.core.HazelcastInstanceNotActiveException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.ArgumentCaptor;
import org.sonar.process.LoggingRule;

@@ -39,9 +39,10 @@ import static org.mockito.Mockito.when;
import static org.slf4j.event.Level.DEBUG;
import static org.slf4j.event.Level.ERROR;

public class HealthStateRefresherTest {
@Rule
public final LoggingRule logging = new LoggingRule(HealthStateRefresher.class);
class HealthStateRefresherTest {

@RegisterExtension
private final LoggingRule logging = new LoggingRule(HealthStateRefresher.class);

private final Random random = new Random();
private final NodeDetailsTestSupport testSupport = new NodeDetailsTestSupport(random);
@@ -52,7 +53,7 @@ public class HealthStateRefresherTest {
private final HealthStateRefresher underTest = new HealthStateRefresher(executorService, nodeHealthProvider, sharedHealthState);

@Test
public void start_adds_runnable_with_10_second_delay_and_initial_delay_putting_NodeHealth_from_provider_into_SharedHealthState() {
void start_adds_runnable_with_10_second_delay_and_initial_delay_putting_NodeHealth_from_provider_into_SharedHealthState() {
ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
NodeHealth[] nodeHealths = {
testSupport.randomNodeHealth(),
@@ -84,7 +85,7 @@ public class HealthStateRefresherTest {
}

@Test
public void stop_whenCalled_hasNoEffect() {
void stop_whenCalled_hasNoEffect() {
underTest.stop();

verify(sharedHealthState).clearMine();
@@ -92,7 +93,7 @@ public class HealthStateRefresherTest {
}

@Test
public void stop_whenThrowHazelcastInactiveException_shouldSilenceError() {
void stop_whenThrowHazelcastInactiveException_shouldSilenceError() {
logging.setLevel(DEBUG);
SharedHealthState sharedHealthStateMock = mock(SharedHealthState.class);
doThrow(HazelcastInstanceNotActiveException.class).when(sharedHealthStateMock).clearMine();
@@ -104,7 +105,7 @@ public class HealthStateRefresherTest {
}

@Test
public void start_whenHazelcastIsNotActive_shouldNotLogErrors() {
void start_whenHazelcastIsNotActive_shouldNotLogErrors() {
logging.setLevel(DEBUG);
doThrow(new HazelcastInstanceNotActiveException()).when(sharedHealthState).writeMine(any());


+ 9
- 1
server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryRule.java View File

@@ -27,6 +27,8 @@ import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.sonar.api.resources.Language;
import org.sonar.api.rule.RuleKey;
@@ -35,10 +37,16 @@ import org.sonar.db.rule.RuleDto;

import static com.google.common.base.Preconditions.checkState;

public class BuiltInQProfileRepositoryRule extends ExternalResource implements BuiltInQProfileRepository {
public class BuiltInQProfileRepositoryRule extends ExternalResource
implements BuiltInQProfileRepository, BeforeEachCallback {
private boolean initializeCalled = false;
private List<BuiltInQProfile> profiles = new ArrayList<>();

@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {
before();
}

@Override
protected void before() {
this.initializeCalled = false;

+ 7
- 7
server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileLoaderTest.java View File

@@ -19,19 +19,19 @@
*/
package org.sonar.server.qualityprofile.builtin;

import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import static org.assertj.core.api.Assertions.assertThat;

public class BuiltInQProfileLoaderTest {
@Rule
public BuiltInQProfileRepositoryRule builtInQProfileRepositoryRule = new BuiltInQProfileRepositoryRule();
class BuiltInQProfileLoaderTest {
@RegisterExtension
private final BuiltInQProfileRepositoryRule builtInQProfileRepositoryRule = new BuiltInQProfileRepositoryRule();

private BuiltInQProfileLoader underTest = new BuiltInQProfileLoader(builtInQProfileRepositoryRule);
private final BuiltInQProfileLoader underTest = new BuiltInQProfileLoader(builtInQProfileRepositoryRule);

@Test
public void start_initializes_DefinedQProfileRepository() {
void start_initializes_DefinedQProfileRepository() {
underTest.start();

assertThat(builtInQProfileRepositoryRule.isInitialized()).isTrue();

+ 0
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java View File

@@ -65,7 +65,6 @@ public class GlobalActionTest {
private final NodeInformation nodeInformation = mock(NodeInformation.class);
private final DbClient dbClient = mock(DbClient.class, RETURNS_DEEP_STUBS);
private final IssueIndexSyncProgressChecker indexSyncProgressChecker = mock(IssueIndexSyncProgressChecker.class);
private final BranchFeatureRule branchFeature = new BranchFeatureRule();
private final PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
private final WebAnalyticsLoader webAnalyticsLoader = mock(WebAnalyticsLoader.class);
private final DefaultAdminCredentialsVerifier defaultAdminCredentialsVerifier = mock(DefaultAdminCredentialsVerifier.class);

+ 0
- 341
sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java View File

@@ -1,341 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.sonarqube.ws.client;

import com.google.protobuf.Parser;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Assertions;
import org.assertj.core.data.MapEntry;
import org.junit.rules.ExternalResource;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;

/**
* Convenient rule to test a subclass of {@link BaseService}.
*
* <p>
* Declaration sample:
* <pre>
* {@literal @}Rule
* public ServiceTester<PermissionsService> serviceTester = new ServiceTester&lt;&gt;(new PermissionsService(mock(WsConnector.class)));
*
* private PermissionsService underTest = serviceTester.getInstanceUnderTest();
* </pre>
* </p>
*
* <p>
* Method {@link #getInstanceUnderTest()} will return an instance of the class under test which will be instrumented
* and will allow recording internal calls to {@link BaseService#call(BaseRequest, Parser)} and
* {@link BaseService#call(WsRequest)}.
* </p>
* <p>
* Argument of calls to these method will be logged and can be accessed through {@link #getGetCalls()}, {@link #getPostCalls()}
* and {@link #getRawCalls()} depending on whether they are made respectively with {@link GetRequest}, {@link PostRequest}
* or other subclass of {@link BaseRequest}.
* </p>
* <p>
* For convenience, when one is testing a single Ws call, on case use {@link #getGetRequest()} (and its associated
* {@link #getGetParser()}) or {@link #getPostRequest()} (and its associated {@link #getPostParser()}). Those three
* method will make the appropriate assertions assuming that only a single GET (or POST) request has been made.
* </p>
* <p>
* Last but not least, to easily verify the content of a {@link GetRequest} (or a {@link PostRequest}), one can use
* methods {@link #assertThat(GetRequest)} (or {@link #assertThat(PostRequest)}) to write assertions on a
* {@link GetRequest} (or {@link PostRequest}) returned by methods of this Rule.
* </p>
*
* <p>
* Assertion usage sample:
* <pre>
* PostRequest postRequest = serviceTester.getPostRequest();
* serviceTester.assertThat(postRequest)
* .hasPath("add_group")
* .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
* .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
* .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
* .hasParam(PARAM_GROUP_ID, GROUP_ID_VALUE)
* .hasParam(PARAM_GROUP_NAME, GROUP_NAME_VALUE)
* .andNoOtherParam();
* </pre>
* </p>
*
*/
public class ServiceTester<T extends BaseService> extends ExternalResource {

private final T underTest;
private final List<GetCall> getCalls = new ArrayList<>();
private final List<PostCall> postCalls = new ArrayList<>();
private final List<RawCall> rawCalls = new ArrayList<>();

/**
* @param underTestInstance an instance of the type to test. Use {@link #getInstanceUnderTest()} to retrieve the
* instrumented instance to use in your test.
*/
public ServiceTester(T underTestInstance) {
this.underTest = spy(underTestInstance);
}

@Override
protected void before() throws Throwable {
Answer<Object> answer = new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
Object request = arguments[0];
Parser<?> parser = arguments.length == 2 ? (Parser<?>) arguments[1] : null;
if (request instanceof PostRequest) {
postCalls.add(new PostCall((PostRequest) request, parser));
} else if (request instanceof GetRequest) {
getCalls.add(new GetCall((GetRequest) request, parser));
} else {
rawCalls.add(new RawCall((WsRequest) request));
}
return null;
}
};
doAnswer(answer).when(this.underTest).call(any(GetRequest.class), any(Parser.class));
doAnswer(answer).when(this.underTest).call(any(WsRequest.class));
}

@Override
protected void after() {
this.getCalls.clear();
}

public T getInstanceUnderTest() {
return underTest;
}

public List<GetCall> getGetCalls() {
return getCalls;
}

@CheckForNull
public GetRequest getGetRequest() {
assertSingleGetCall();
return (GetRequest) getCalls.iterator().next().getRequest();
}

public RequestAssert<?> assertThat(GetRequest getRequest) {
return new RequestAssert<>(getRequest);
}

public RequestAssert<?> assertThat(PostRequest postRequest) {
return new RequestAssert<>(postRequest);
}

@CheckForNull
public Parser<?> getGetParser() {
assertSingleGetCall();
return getCalls.iterator().next().getParser();
}

public List<PostCall> getPostCalls() {
return postCalls;
}

public PostRequest getPostRequest() {
assertSinglePostCall();
return (PostRequest) postCalls.iterator().next().getRequest();
}

@CheckForNull
public Parser<?> getPostParser() {
assertSinglePostCall();
return postCalls.iterator().next().getParser();
}

private void assertSingleGetCall() {
Assertions.assertThat(getCalls).hasSize(1);
Assertions.assertThat(postCalls).isEmpty();
Assertions.assertThat(rawCalls).isEmpty();
}

private void assertSinglePostCall() {
Assertions.assertThat(postCalls).hasSize(1);
Assertions.assertThat(getRawCalls()).isEmpty();
Assertions.assertThat(rawCalls).isEmpty();
}

public List<RawCall> getRawCalls() {
return rawCalls;
}

@Immutable
public static final class GetCall extends CallWithParser<RequestWithoutPayload<GetRequest>> {

public GetCall(GetRequest getRequest, @Nullable Parser<?> parser) {
super(getRequest, parser);
}

}

@Immutable
public static final class PostCall extends CallWithParser<RequestWithPayload<PostRequest>> {

public PostCall(PostRequest postRequest, @Nullable Parser<?> parser) {
super(postRequest, parser);
}
}

@Immutable
public static final class RawCall {
private final WsRequest wsRequest;

public RawCall(WsRequest wsRequest) {
this.wsRequest = wsRequest;
}

public WsRequest getWsRequest() {
return wsRequest;
}

@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RawCall rawCalls = (RawCall) o;
return Objects.equals(wsRequest, rawCalls.wsRequest);
}

@Override
public int hashCode() {
return Objects.hash(wsRequest);
}
}

public static abstract class CallWithParser<T extends BaseRequest<T>> {
private final T request;
private final Parser<?> parser;

public CallWithParser(T request, @Nullable Parser<?> parser) {
this.request = request;
this.parser = parser;
}

public T getRequest() {
return request;
}

public Parser<?> getParser() {
return parser;
}

@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CallWithParser getCall = (CallWithParser) o;
return Objects.equals(request, getCall.request) &&
Objects.equals(parser, getCall.request);
}

@Override
public int hashCode() {
return Objects.hash(request, parser);
}
}

public final class RequestAssert<T extends BaseRequest<T>> extends AbstractAssert<RequestAssert<T>, BaseRequest<T>> {
private final List<MapEntry<String, String>> assertedParams = new ArrayList<>();

protected RequestAssert(T actual) {
super(actual, RequestAssert.class);
}

public RequestAssert hasPath(String path) {
isNotNull();

String expectedPath = underTest.controller + "/" + path;
if (!Objects.equals(actual.getPath(), expectedPath)) {
failWithMessage("Expected path to be <%s> but was <%s>", expectedPath, actual.getPath());
}

return this;
}

public RequestAssert hasParam(String key, String value) {
isNotNull();

MapEntry<String, String> entry = MapEntry.entry(key, value);
Assertions.assertThat(actual.getParams()).contains(entry);
this.assertedParams.add(entry);

return this;
}

public RequestAssert hasParam(String key, int value) {
isNotNull();

MapEntry<String, String> entry = MapEntry.entry(key, String.valueOf(value));
Assertions.assertThat(actual.getParams()).contains(entry);
this.assertedParams.add(entry);

return this;
}

public RequestAssert hasParam(String key, boolean value) {
isNotNull();

MapEntry<String, String> entry = MapEntry.entry(key, String.valueOf(value));
Assertions.assertThat(actual.getParams()).contains(entry);
this.assertedParams.add(entry);

return this;
}

public RequestAssert hasParam(String key, List<String> values) {
isNotNull();

MapEntry<String, String> entry = MapEntry.entry(key, values.toString());
Assertions.assertThat(actual.getParameters().getValues(key)).containsExactly(values.toArray(new String[0]));
this.assertedParams.add(entry);

return this;
}

public RequestAssert andNoOtherParam() {
isNotNull();

Assertions.assertThat(actual.getParams()).hasSize(assertedParams.size());

return this;
}

}
}

Loading…
Cancel
Save