From 589f9156ea869774a828a8b69081d8fb4fdbcac6 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 30 Jun 2017 08:38:06 +0200 Subject: [PATCH] make use of TestExceutionListener, remove static access to context (#551) Signed-off-by: Michael Hirsch --- .../repository/test/TestConfiguration.java | 21 -------- .../test/matcher/EventVerifier.java | 50 +++++++++---------- .../test/util/AbstractIntegrationTest.java | 14 +++--- .../test/util/CleanRepositoryRule.java | 21 -------- .../util/CleanupTestExecutionListener.java | 33 ++++++++++++ .../util/JpaTestRepositoryManagement.java | 3 +- .../test/util/TestContextProvider.java | 27 ---------- .../test/util/TestRepositoryManagement.java | 22 -------- 8 files changed, 65 insertions(+), 126 deletions(-) delete mode 100644 hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanRepositoryRule.java create mode 100644 hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanupTestExecutionListener.java delete mode 100644 hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestContextProvider.java delete mode 100644 hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestRepositoryManagement.java diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java index 0b9820e74..03f535661 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java @@ -23,13 +23,9 @@ import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.cache.TenantAwareCacheManager; import org.eclipse.hawkbit.event.BusProtoStuffMessageConverter; import org.eclipse.hawkbit.repository.RolloutStatusCache; -import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver; -import org.eclipse.hawkbit.repository.test.util.JpaTestRepositoryManagement; -import org.eclipse.hawkbit.repository.test.util.TestContextProvider; -import org.eclipse.hawkbit.repository.test.util.TestRepositoryManagement; import org.eclipse.hawkbit.repository.test.util.TestdataFactory; import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; @@ -48,7 +44,6 @@ import org.springframework.cache.guava.GuavaCacheManager; import org.springframework.cloud.bus.ConditionalOnBusEnabled; import org.springframework.cloud.bus.ServiceMatcher; import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -106,12 +101,6 @@ public class TestConfiguration implements AsyncConfigurer { return new ArtifactFilesystemRepository(artifactFilesystemProperties); } - @Bean - public TestRepositoryManagement testRepositoryManagement(final SystemSecurityContext systemSecurityContext, - final SystemManagement systemManagement) { - return new JpaTestRepositoryManagement(cacheManager(), systemSecurityContext, systemManagement); - } - @Bean public TestdataFactory testdataFactory() { return new TestdataFactory(); @@ -202,14 +191,4 @@ public class TestConfiguration implements AsyncConfigurer { public MessageConverter busProtoBufConverter() { return new BusProtoStuffMessageConverter(); } - - /** - * {@link TestContextProvider} bean. - * - * @return a new {@link TestContextProvider} - */ - @Bean - public ApplicationContextAware applicationContextProvider() { - return new TestContextProvider(); - } } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java index e09a42c26..6fabea24d 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.test.matcher; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.equalTo; +import java.lang.reflect.Method; import java.util.Iterator; import java.util.Optional; import java.util.Set; @@ -22,17 +23,15 @@ import java.util.stream.Stream; import org.eclipse.hawkbit.repository.event.remote.RemoteIdEvent; import org.eclipse.hawkbit.repository.event.remote.RemoteTenantAwareEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; -import org.eclipse.hawkbit.repository.test.util.TestContextProvider; import org.junit.Assert; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.bus.event.RemoteApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.event.ApplicationEventMulticaster; +import org.springframework.test.context.TestContext; +import org.springframework.test.context.support.AbstractTestExecutionListener; import com.google.common.collect.ConcurrentHashMultiset; import com.google.common.collect.Multiset; @@ -43,35 +42,34 @@ import com.jayway.awaitility.core.ConditionTimeoutException; /** * Test rule to setup and verify the event count for a method. */ -public class EventVerifier implements TestRule { +public class EventVerifier extends AbstractTestExecutionListener { private static final Logger LOGGER = LoggerFactory.getLogger(EventVerifier.class); private EventCaptor eventCaptor; @Override - public Statement apply(final Statement test, final Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - - final Optional expectedEvents = getExpectationsFrom(description); - expectedEvents.ifPresent(events -> beforeTest()); - try { - test.evaluate(); - expectedEvents.ifPresent(events -> afterTest(events)); - } finally { - expectedEvents.ifPresent(listener -> removeEventListener()); - } - } - }; + public void beforeTestMethod(final TestContext testContext) throws Exception { + final Optional expectedEvents = getExpectationsFrom(testContext.getTestMethod()); + expectedEvents.ifPresent(events -> beforeTest(testContext)); } - private Optional getExpectationsFrom(final Description description) { - return Optional.ofNullable(description.getAnnotation(ExpectEvents.class)).map(ExpectEvents::value); + @Override + public void afterTestMethod(final TestContext testContext) throws Exception { + final Optional expectedEvents = getExpectationsFrom(testContext.getTestMethod()); + try { + expectedEvents.ifPresent(events -> afterTest(events)); + } finally { + expectedEvents.ifPresent(listener -> removeEventListener(testContext)); + } } - private void beforeTest() { - final ConfigurableApplicationContext context = TestContextProvider.getContext(); + private Optional getExpectationsFrom(final Method testMethod) { + return Optional.ofNullable(testMethod.getAnnotation(ExpectEvents.class)).map(ExpectEvents::value); + } + + private void beforeTest(final TestContext testContext) { + final ConfigurableApplicationContext context = (ConfigurableApplicationContext) testContext + .getApplicationContext(); eventCaptor = new EventCaptor(); context.addApplicationListener(eventCaptor); } @@ -111,8 +109,8 @@ public class EventVerifier implements TestRule { } - private void removeEventListener() { - final ApplicationEventMulticaster multicaster = TestContextProvider.getContext() + private void removeEventListener(final TestContext testContext) { + final ApplicationEventMulticaster multicaster = testContext.getApplicationContext() .getBean(ApplicationEventMulticaster.class); multicaster.removeApplicationListener(eventCaptor); } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 08610531c..fea130c9b 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.test.util; import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE; import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE; -import static org.junit.rules.RuleChain.outerRule; import java.io.File; import java.io.IOException; @@ -61,7 +60,6 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; -import org.junit.rules.RuleChain; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import org.junit.runner.RunWith; @@ -82,6 +80,8 @@ import org.springframework.hateoas.MediaTypes; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.TestExecutionListeners.MergeMode; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; @@ -99,6 +99,11 @@ import org.springframework.web.context.WebApplicationContext; // refreshed we e.g. get two instances of CacheManager which leads to very // strange test failures. @DirtiesContext(classMode = ClassMode.AFTER_CLASS) +// Cleaning repository will fire "delete" events. We won't count them to the +// test execution. So, the order execution between EventVerifier and Cleanup is +// important! +@TestExecutionListeners(inheritListeners = true, listeners = { EventVerifier.class, + CleanupTestExecutionListener.class }, mergeMode = MergeMode.MERGE_WITH_DEFAULTS) public abstract class AbstractIntegrationTest implements EnvironmentAware { private static final Logger LOG = LoggerFactory.getLogger(AbstractIntegrationTest.class); @@ -201,11 +206,6 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @Autowired protected ServiceMatcher serviceMatcher; - @Rule - // Cleaning repository will fire "delete" events. We won't count them to the - // test execution. So there is order between both rules: - public RuleChain ruleChain = outerRule(new CleanRepositoryRule()).around(new EventVerifier()); - @Rule public final WithSpringAuthorityRule securityRule = new WithSpringAuthorityRule(); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanRepositoryRule.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanRepositoryRule.java deleted file mode 100644 index 80ff8ced5..000000000 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanRepositoryRule.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations 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.rules.ExternalResource; - -public class CleanRepositoryRule extends ExternalResource { - - @Override - protected void after() { - final TestRepositoryManagement repository = TestContextProvider.getContext() - .getBean(TestRepositoryManagement.class); - repository.clearTestRepository(); - } -} diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanupTestExecutionListener.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanupTestExecutionListener.java new file mode 100644 index 000000000..500ff754c --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/CleanupTestExecutionListener.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations 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.eclipse.hawkbit.cache.TenantAwareCacheManager; +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.security.SystemSecurityContext; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.TestContext; +import org.springframework.test.context.TestExecutionListener; +import org.springframework.test.context.support.AbstractTestExecutionListener; + +/** + * A spring {@link TestExecutionListener} which cleansup the repository after + * each test-method. + */ +public class CleanupTestExecutionListener extends AbstractTestExecutionListener { + + @Override + public void afterTestMethod(final TestContext testContext) throws Exception { + + final ApplicationContext applicationContext = testContext.getApplicationContext(); + new JpaTestRepositoryManagement(applicationContext.getBean(TenantAwareCacheManager.class), + applicationContext.getBean(SystemSecurityContext.class), + applicationContext.getBean(SystemManagement.class)).clearTestRepository(); + } +} diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java index 59c640586..18587d4a0 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java @@ -20,7 +20,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; -public class JpaTestRepositoryManagement implements TestRepositoryManagement { +public class JpaTestRepositoryManagement { private static final Logger LOGGER = LoggerFactory.getLogger(JpaTestRepositoryManagement.class); private static final Pageable PAGE = new PageRequest(0, 400, new Sort(Direction.ASC, "id")); @@ -48,7 +48,6 @@ public class JpaTestRepositoryManagement implements TestRepositoryManagement { this.systemManagement = systemManagement; } - @Override public void clearTestRepository() { deleteAllRepos(); cacheManager.getDirectCacheNames().forEach(name -> cacheManager.getDirectCache(name).clear()); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestContextProvider.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestContextProvider.java deleted file mode 100644 index 8bd38808d..000000000 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestContextProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations 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.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ConfigurableApplicationContext; - -public class TestContextProvider implements ApplicationContextAware { - - private static ApplicationContext applicationContext; - - public static ConfigurableApplicationContext getContext() { - return (ConfigurableApplicationContext) applicationContext; - } - - @Override - public void setApplicationContext(final ApplicationContext context) { - applicationContext = context; - } -} diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestRepositoryManagement.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestRepositoryManagement.java deleted file mode 100644 index 482c7725c..000000000 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestRepositoryManagement.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations 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; - -/** - * Repository support for tests. - * - */ -@FunctionalInterface -public interface TestRepositoryManagement { - /** - * Empty the test repository. - */ - void clearTestRepository(); - -}