@@ -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() | |||
} |
@@ -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()); |
@@ -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 { |
@@ -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')) | |||
@@ -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(); |
@@ -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(); | |||
} | |||
} |
@@ -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) { |
@@ -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) { |
@@ -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(); |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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() |
@@ -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); | |||
@@ -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(); | |||
} | |||
} |
@@ -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() |
@@ -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(); | |||
} | |||
} |
@@ -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); |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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), |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
@@ -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); | |||
@@ -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(); |
@@ -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); | |||
@@ -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); |
@@ -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"); |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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; |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); |
@@ -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; |
@@ -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); |
@@ -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(); |
@@ -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 |
@@ -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() | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -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()); | |||
@@ -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; |
@@ -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(); |
@@ -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); |
@@ -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<>(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; | |||
} | |||
} | |||
} |