Refactored TimestampCalculator to be static and adjusted tests using PowerMock.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>
This commit is contained in:
Dominik Herbst
2016-10-14 10:32:10 +02:00
parent 36656826f8
commit d81619a1a0
9 changed files with 57 additions and 52 deletions

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.autoconfigure.repository; package org.eclipse.hawkbit.autoconfigure.repository;
import org.eclipse.hawkbit.EnableJpaRepository; import org.eclipse.hawkbit.EnableJpaRepository;
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyResolver; import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyResolver;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -34,7 +33,7 @@ public class JpaRepositoryAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public VirtualPropertyReplacer virtualPropertyReplacer() { public VirtualPropertyReplacer virtualPropertyReplacer() {
return new VirtualPropertyResolver(new TimestampCalculator()); return new VirtualPropertyResolver();
} }
} }

View File

@@ -22,7 +22,7 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
* Therefore tenant specific configuration may be considered. * Therefore tenant specific configuration may be considered.
* *
*/ */
public class TimestampCalculator { public final class TimestampCalculator {
/** /**
* Calculates the overdue timestamp (<em>overdue_ts</em>) based on the * Calculates the overdue timestamp (<em>overdue_ts</em>) based on the
@@ -36,20 +36,20 @@ public class TimestampCalculator {
* @return <em>overdue_ts</em> in milliseconds since Unix epoch as long * @return <em>overdue_ts</em> in milliseconds since Unix epoch as long
* value * value
*/ */
public long calculateOverdueTimestamp() { public static long calculateOverdueTimestamp() {
return Instant.now().toEpochMilli() - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis() return Instant.now().toEpochMilli() - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis()
- getDurationForKey(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL).toMillis(); - getDurationForKey(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL).toMillis();
} }
private Duration getDurationForKey(TenantConfigurationKey key) { private static Duration getDurationForKey(TenantConfigurationKey key) {
return DurationHelper.formattedStringToDuration(getRawStringForKey(key)); return DurationHelper.formattedStringToDuration(getRawStringForKey(key));
} }
private String getRawStringForKey(TenantConfigurationKey key) { private static String getRawStringForKey(TenantConfigurationKey key) {
return getTenantConfigurationManagement().getConfigurationValue(key, String.class).getValue(); return getTenantConfigurationManagement().getConfigurationValue(key, String.class).getValue();
} }
protected TenantConfigurationManagement getTenantConfigurationManagement() { public static TenantConfigurationManagement getTenantConfigurationManagement() {
return TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement(); return TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement();
} }
} }

View File

@@ -8,12 +8,17 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.rsql; package org.eclipse.hawkbit.repository.jpa.rsql;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import org.apache.commons.lang3.text.StrLookup; import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrSubstitutor; import org.apache.commons.lang3.text.StrSubstitutor;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator; import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
/** /**
* Adds macro capabilities to RSQL expressions that are used to filter for * Adds macro capabilities to RSQL expressions that are used to filter for
@@ -43,21 +48,8 @@ import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
*/ */
public class VirtualPropertyResolver extends StrLookup<String> implements VirtualPropertyReplacer { public class VirtualPropertyResolver extends StrLookup<String> implements VirtualPropertyReplacer {
private final TimestampCalculator timestampCalculator;
private StrSubstitutor substitutor; private StrSubstitutor substitutor;
/**
* Instantiates a new virtual property resolver with the given timestamp
* calculator
*
* @param timestampCalculator
* calculates timestamps
*/
public VirtualPropertyResolver(TimestampCalculator timestampCalculator) {
this.timestampCalculator = timestampCalculator;
}
@Override @Override
public String lookup(String rhs) { public String lookup(String rhs) {
String resolved = null; String resolved = null;
@@ -65,7 +57,7 @@ public class VirtualPropertyResolver extends StrLookup<String> implements Virtua
if ("now_ts".equalsIgnoreCase(rhs)) { if ("now_ts".equalsIgnoreCase(rhs)) {
resolved = String.valueOf(Instant.now().toEpochMilli()); resolved = String.valueOf(Instant.now().toEpochMilli());
} else if ("overdue_ts".equalsIgnoreCase(rhs)) { } else if ("overdue_ts".equalsIgnoreCase(rhs)) {
resolved = String.valueOf(getTimestampCalculator().calculateOverdueTimestamp()); resolved = String.valueOf(TimestampCalculator.calculateOverdueTimestamp());
} }
return resolved; return resolved;
} }
@@ -79,7 +71,4 @@ public class VirtualPropertyResolver extends StrLookup<String> implements Virtua
return substitutor.replace(input); return substitutor.replace(input);
} }
TimestampCalculator getTimestampCalculator() {
return timestampCalculator;
}
} }

View File

@@ -141,6 +141,16 @@
<artifactId>fest-assert</artifactId> <artifactId>fest-assert</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -309,7 +309,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
if (filterParams.getOverdueState() != null) { if (filterParams.getOverdueState() != null) {
specList.add( specList.add(
TargetSpecifications.isOverdue(new TimestampCalculator().calculateOverdueTimestamp())); TargetSpecifications.isOverdue(TimestampCalculator.calculateOverdueTimestamp()));
} }
if (filterParams.getFilterByDistributionId() != null) { if (filterParams.getFilterByDistributionId() != null) {
specList.add( specList.add(

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Matchers.*; import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
@@ -36,28 +37,27 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Spy; import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories; import ru.yandex.qatools.allure.annotations.Stories;
@RunWith(MockitoJUnitRunner.class) @RunWith(PowerMockRunner.class)
@Features("Component Tests - Repository") @Features("Component Tests - Repository")
@Stories("RSQL search utility") @Stories("RSQL search utility")
@PrepareForTest(TimestampCalculator.class)
// TODO: fully document tests -> @Description for long text and reasonable // TODO: fully document tests -> @Description for long text and reasonable
// method name as short text // method name as short text
public class RSQLUtilityTest { public class RSQLUtilityTest {
@Spy @Spy
private VirtualPropertyResolver macroResolver = new VirtualPropertyResolver(new TimestampCalculator()); private VirtualPropertyResolver macroResolver = new VirtualPropertyResolver();
@Mock @Mock
private TenantConfigurationManagement confMgmt; private TenantConfigurationManagement confMgmt;
@Mock
private TimestampCalculator timestampCalculator;
@Mock @Mock
private Root<Object> baseSoftwareModuleRootMock; private Root<Object> baseSoftwareModuleRootMock;
@@ -315,10 +315,10 @@ public class RSQLUtilityTest {
Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMacroLookup()) Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMacroLookup())
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
// verfication // verification
verify(macroResolver, times(1)).lookup(overdueProp); verify(macroResolver).lookup(overdueProp);
// the macro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder: // the macro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder:
verify(criteriaBuilderMock, times(1)).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)), verify(criteriaBuilderMock).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)),
eq(overduePropPlaceholder)); eq(overduePropPlaceholder));
} }
@@ -328,12 +328,8 @@ public class RSQLUtilityTest {
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)) when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class))
.thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL); .thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL);
when(macroResolver.getTimestampCalculator()).thenReturn(new TimestampCalculator() { mockStatic(TimestampCalculator.class);
@Override when(TimestampCalculator.getTenantConfigurationManagement()).thenReturn(confMgmt);
protected TenantConfigurationManagement getTenantConfigurationManagement() {
return confMgmt;
}
});
return macroResolver; return macroResolver;
} }

View File

@@ -12,6 +12,8 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import java.time.Instant; import java.time.Instant;
import org.apache.commons.lang3.text.StrSubstitutor; import org.apache.commons.lang3.text.StrSubstitutor;
@@ -25,19 +27,21 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Spy; import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories; import ru.yandex.qatools.allure.annotations.Stories;
@Features("Unit Tests - Repository") @Features("Unit Tests - Repository")
@Stories("Placeholder resolution for virtual properties") @Stories("Placeholder resolution for virtual properties")
@RunWith(MockitoJUnitRunner.class) @RunWith(PowerMockRunner.class)
@PrepareForTest(TimestampCalculator.class)
public class VirtualPropertyResolverTest { public class VirtualPropertyResolverTest {
@Spy @Spy
private VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver(new TimestampCalculator()); private VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver();
@Mock @Mock
private TenantConfigurationManagement confMgmt; private TenantConfigurationManagement confMgmt;
@@ -59,12 +63,8 @@ public class VirtualPropertyResolverTest {
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)) when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class))
.thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL); .thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL);
when(resolverUnderTest.getTimestampCalculator()).thenReturn(new TimestampCalculator() { mockStatic(TimestampCalculator.class);
@Override when(TimestampCalculator.getTenantConfigurationManagement()).thenReturn(confMgmt);
protected TenantConfigurationManagement getTenantConfigurationManagement() {
return confMgmt;
}
});
substitutor = new StrSubstitutor(resolverUnderTest, substitutor = new StrSubstitutor(resolverUnderTest,
StrSubstitutor.DEFAULT_PREFIX, StrSubstitutor.DEFAULT_PREFIX,

View File

@@ -16,7 +16,6 @@ import org.eclipse.hawkbit.api.PropertyBasedArtifactUrlHandler;
import org.eclipse.hawkbit.cache.CacheConstants; import org.eclipse.hawkbit.cache.CacheConstants;
import org.eclipse.hawkbit.cache.TenancyCacheManager; import org.eclipse.hawkbit.cache.TenancyCacheManager;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager; import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyResolver; import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyResolver;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
@@ -138,7 +137,7 @@ public class TestConfiguration implements AsyncConfigurer {
*/ */
@Bean @Bean
public VirtualPropertyReplacer virtualPropertyReplacer() { public VirtualPropertyReplacer virtualPropertyReplacer() {
return new VirtualPropertyResolver(new TimestampCalculator()); return new VirtualPropertyResolver();
} }
} }

14
pom.xml
View File

@@ -133,7 +133,7 @@
<org.easytesting.version>2.0M10</org.easytesting.version> <org.easytesting.version>2.0M10</org.easytesting.version>
<allure.version>1.4.22</allure.version> <allure.version>1.4.22</allure.version>
<eclipselink.version>2.6.2</eclipselink.version> <eclipselink.version>2.6.2</eclipselink.version>
<org.powermock.version>1.5.4</org.powermock.version> <org.powermock.version>1.6.5</org.powermock.version>
<pl.pragmatists.version>1.0.2</pl.pragmatists.version> <pl.pragmatists.version>1.0.2</pl.pragmatists.version>
<guava.version>19.0</guava.version> <guava.version>19.0</guava.version>
<mariadb-java-client.version>1.5.2</mariadb-java-client.version> <mariadb-java-client.version>1.5.2</mariadb-java-client.version>
@@ -675,6 +675,18 @@
<version>${pl.pragmatists.version}</version> <version>${pl.pragmatists.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${org.powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${org.powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.mariadb.jdbc</groupId> <groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId> <artifactId>mariadb-java-client</artifactId>