Migration to JUnit5 as default test runtime (#1082)

* Migrate tests to JUnit5

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>

* REST docs tests migrated to JUnit5

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>

* Migrated security and UI tests to JUnit5

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>

* Migrated management tests to JUnit5

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>

* Reflecting changes from JUnit5 migration

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>

* Fix RabbitMQ test detection

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>

* Drop support for JUnit4

Signed-off-by: Dominic Schabel <dominic.schabel@bosch.io>
This commit is contained in:
Dominic Schabel
2021-03-15 13:40:40 +01:00
committed by GitHub
parent 82ab18cf42
commit 81defa10a6
140 changed files with 572 additions and 657 deletions

View File

@@ -62,14 +62,11 @@ import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -89,12 +86,11 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.TestExecutionListeners.MergeMode;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import com.google.common.io.Files;
@RunWith(SpringRunner.class)
@ActiveProfiles({ "test" })
@ExtendWith({JUnitTestLoggerExtension.class, WithSpringAuthorityRule.class})
@WithUser(principal = "bumlux", allSpPermissions = true, authorities = { CONTROLLER_ROLE, SYSTEM_ROLE })
@SpringBootTest
@ContextConfiguration(classes = { TestConfiguration.class, TestSupportBinderAutoConfiguration.class })
@@ -208,28 +204,6 @@ public abstract class AbstractIntegrationTest {
@Autowired
protected ApplicationEventPublisher eventPublisher;
@Rule
public final WithSpringAuthorityRule securityRule = new WithSpringAuthorityRule();
@Rule
public TestWatcher testLifecycleLoggerRule = new TestWatcher() {
@Override
protected void starting(final Description description) {
LOG.info("Starting Test {}...", description.getMethodName());
}
@Override
protected void succeeded(final Description description) {
LOG.info("Test {} succeeded.", description.getMethodName());
}
@Override
protected void failed(final Throwable e, final Description description) {
LOG.error("Test {} failed with {}.", description.getMethodName(), e);
}
};
protected DistributionSetAssignmentResult assignDistributionSet(final long dsID, final String controllerId) {
return assignDistributionSet(dsID, controllerId, ActionType.FORCED);
}
@@ -294,7 +268,7 @@ public abstract class AbstractIntegrationTest {
* @param controllerId
* is the ID for the controller to which the distribution set is
* being assigned
* @param maintenanceSchedule
* @param maintenanceWindowSchedule
* is the cron expression to be used for scheduling the
* maintenance window. Expression has 6 mandatory fields and 1
* last optional field: "second minute hour dayofmonth month
@@ -373,27 +347,27 @@ public abstract class AbstractIntegrationTest {
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.FINISHED));
}
@Before
public void before() throws Exception {
@BeforeEach
public void beforeAll() throws Exception {
final String description = "Updated description.";
osType = securityRule
osType = WithSpringAuthorityRule
.runAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_OS));
osType = securityRule.runAsPrivileged(() -> softwareModuleTypeManagement
osType = WithSpringAuthorityRule.runAsPrivileged(() -> softwareModuleTypeManagement
.update(entityFactory.softwareModuleType().update(osType.getId()).description(description)));
appType = securityRule.runAsPrivileged(
appType = WithSpringAuthorityRule.runAsPrivileged(
() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_APP, Integer.MAX_VALUE));
appType = securityRule.runAsPrivileged(() -> softwareModuleTypeManagement
appType = WithSpringAuthorityRule.runAsPrivileged(() -> softwareModuleTypeManagement
.update(entityFactory.softwareModuleType().update(appType.getId()).description(description)));
runtimeType = securityRule
runtimeType = WithSpringAuthorityRule
.runAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_RT));
runtimeType = securityRule.runAsPrivileged(() -> softwareModuleTypeManagement
runtimeType = WithSpringAuthorityRule.runAsPrivileged(() -> softwareModuleTypeManagement
.update(entityFactory.softwareModuleType().update(runtimeType.getId()).description(description)));
standardDsType = securityRule.runAsPrivileged(() -> testdataFactory.findOrCreateDefaultTestDsType());
standardDsType = WithSpringAuthorityRule.runAsPrivileged(() -> testdataFactory.findOrCreateDefaultTestDsType());
// publish the reset counter market event to reset the counters after
// setup. The setup is transparent by the test and its @ExpectedEvent
@@ -408,7 +382,7 @@ public abstract class AbstractIntegrationTest {
private static String artifactDirectory = Files.createTempDir().getAbsolutePath() + "/"
+ RandomStringUtils.randomAlphanumeric(20);
@After
@AfterEach
public void cleanUp() {
if (new File(artifactDirectory).exists()) {
try {
@@ -419,12 +393,12 @@ public abstract class AbstractIntegrationTest {
}
}
@BeforeClass
@BeforeAll
public static void beforeClass() {
System.setProperty("org.eclipse.hawkbit.repository.file.path", artifactDirectory);
}
@AfterClass
@AfterAll
public static void afterClass() {
if (new File(artifactDirectory).exists()) {
try {

View File

@@ -0,0 +1,35 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.test.util;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestWatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JUnitTestLoggerExtension implements BeforeTestExecutionCallback, TestWatcher {
private static final Logger LOG = LoggerFactory.getLogger(JUnitTestLoggerExtension.class);
@Override
public void testSuccessful(ExtensionContext context) {
LOG.info("Test {} succeeded.", context.getTestMethod());
}
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
LOG.error("Test {} failed with {}.", context.getTestMethod());
}
@Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
LOG.info("Starting Test {}...", context.getTestMethod());
}
}

View File

@@ -19,49 +19,46 @@ import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.im.authentication.UserPrincipal;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
public class WithSpringAuthorityRule implements TestRule {
public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCallback {
private SecurityContext oldContext;
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
// throwable comes from jnuit evaluate signature
@SuppressWarnings("squid:S00112")
public void evaluate() throws Throwable {
final SecurityContext oldContext = before(description);
try {
base.evaluate();
} finally {
after(oldContext);
}
}
};
}
private SecurityContext before(final Description description) {
final SecurityContext oldContext = SecurityContextHolder.getContext();
WithUser annotation = description.getAnnotation(WithUser.class);
if (annotation == null) {
annotation = description.getTestClass().getAnnotation(WithUser.class);
}
public void beforeEach(ExtensionContext context) throws Exception {
oldContext = SecurityContextHolder.getContext();
WithUser annotation = getWithUserAnnotation(context);
if (annotation != null) {
if (annotation.autoCreateTenant()) {
createTenant(annotation.tenantId());
}
setSecurityContext(annotation);
}
return oldContext;
}
private void setSecurityContext(final WithUser annotation) {
private WithUser getWithUserAnnotation(ExtensionContext context) {
if (context.getRequiredTestMethod().isAnnotationPresent(WithUser.class)) {
return context.getRequiredTestMethod().getAnnotation(WithUser.class);
}
if(context.getRequiredTestClass().isAnnotationPresent(WithUser.class)){
return context.getRequiredTestClass().getAnnotation(WithUser.class);
}
return null;
}
@Override
public void afterEach(ExtensionContext context) throws Exception {
SecurityContextHolder.setContext(oldContext);
}
private static void setSecurityContext(final WithUser annotation) {
SecurityContextHolder.setContext(new SecurityContext() {
private static final long serialVersionUID = 1L;
@@ -121,34 +118,11 @@ public class WithSpringAuthorityRule implements TestRule {
});
}
private void after(final SecurityContext oldContext) {
SecurityContextHolder.setContext(oldContext);
}
/**
* Clears the current security context.
*/
public void clear() {
SecurityContextHolder.clearContext();
}
/**
* @param callable
* @return the callable result
* @throws Exception
*/
public <T> T runAsPrivileged(final Callable<T> callable) throws Exception {
public static <T> T runAsPrivileged(final Callable<T> callable) throws Exception {
return runAs(privilegedUser(), callable);
}
/**
*
* @param withUser
* @param callable
* @return callable result
* @throws Exception
*/
public <T> T runAs(final WithUser withUser, final Callable<T> callable) throws Exception {
public static <T> T runAs(final WithUser withUser, final Callable<T> callable) throws Exception {
final SecurityContext oldContext = SecurityContextHolder.getContext();
setSecurityContext(withUser);
if (withUser.autoCreateTenant()) {
@@ -157,17 +131,17 @@ public class WithSpringAuthorityRule implements TestRule {
try {
return callable.call();
} finally {
after(oldContext);
SecurityContextHolder.setContext(oldContext);
}
}
private void createTenant(final String tenantId) {
private static void createTenant(final String tenantId) {
final SecurityContext oldContext = SecurityContextHolder.getContext();
setSecurityContext(privilegedUser());
try {
SystemManagementHolder.getInstance().getSystemManagement().getTenantMetadata(tenantId);
} finally {
after(oldContext);
SecurityContextHolder.setContext(oldContext);
}
}