Replace use of PowerMock with Mockito (#12282)

Mockito now supports all our needs and plays much better with recent Java versions.
Migrating to Mockito also simplifies running the kind of tests that required PowerMock in the past. 

* replace all uses of powermock with mockito-inline
* upgrade mockito to 4.3.1 and fix use of deprecated methods
* import mockito bom to align all our mockito dependencies
* add powermock to forbidden-apis to avoid accidentally reintroducing it in the future
This commit is contained in:
Xavier Léauté 2022-02-27 22:47:09 -08:00 committed by GitHub
parent 1434197ee1
commit d105519558
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 223 additions and 372 deletions

View File

@ -58,3 +58,5 @@ com.google.common.io.BaseEncoding#base64()
@defaultMessage Use com.google.errorprone.annotations.concurrent.GuardedBy
javax.annotation.concurrent.GuardedBy
com.amazonaws.annotation.GuardedBy
org.powermock.** @ Use Mockito instead of Powermock for compatibility with newer Java versions

View File

@ -341,14 +341,12 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>${mockito.version}</version>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -145,26 +145,15 @@
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -26,10 +26,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.guice.GuiceInjectors;
import org.apache.druid.guice.JsonConfigProvider;
@ -43,36 +41,29 @@ import org.apache.druid.query.lookup.namespace.ExtractionNamespace;
import org.apache.druid.query.lookup.namespace.UriExtractionNamespace;
import org.apache.druid.server.DruidNode;
import org.apache.druid.server.lookup.namespace.cache.CacheScheduler;
import org.apache.druid.server.lookup.namespace.cache.NamespaceExtractionCacheManager;
import org.easymock.EasyMock;
import org.easymock.IExpectationSetters;
import org.joda.time.Period;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;
@RunWith(PowerMockRunner.class)
@PrepareForTest({
NamespaceExtractionCacheManager.class,
CacheScheduler.class,
CacheScheduler.VersionedCache.class,
CacheScheduler.Entry.class
})
// defer classloading of the following classes to the system classloader
// since they need to be loaded in the right Java module in JDK9 and above
@PowerMockIgnore({"javax.net.ssl.*", "javax.xml.*", "com.sun.xml.*"})
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.atMostOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class NamespaceLookupExtractorFactoryTest
{
static {
@ -82,13 +73,12 @@ public class NamespaceLookupExtractorFactoryTest
private final ObjectMapper mapper = new DefaultObjectMapper();
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Rule
public ExpectedException expectedException = ExpectedException.none();
private final CacheScheduler scheduler = PowerMock.createStrictMock(CacheScheduler.class);
private final CacheScheduler.Entry entry = PowerMock.createStrictMock(CacheScheduler.Entry.class);
private final CacheScheduler scheduler = mock(CacheScheduler.class);
private final CacheScheduler.Entry entry = mock(CacheScheduler.Entry.class);
private final CacheScheduler.VersionedCache versionedCache =
PowerMock.createStrictMock(CacheScheduler.VersionedCache.class);
mock(CacheScheduler.VersionedCache.class);
@Before
public void setUp()
@ -123,7 +113,6 @@ public class NamespaceLookupExtractorFactoryTest
temporaryFolder.newFolder().toURI(),
null, null,
new UriExtractionNamespace.ObjectMapperFlatDataParser(mapper),
Period.millis(0),
null,
null
@ -144,24 +133,17 @@ public class NamespaceLookupExtractorFactoryTest
@Test
public void testMissingSpec()
{
expectedException.expectMessage("extractionNamespace should be specified");
new NamespaceLookupExtractorFactory(null, null);
Assert.assertThrows(
"extractionNamespace should be specified", NullPointerException.class,
() -> new NamespaceLookupExtractorFactory(null, null)
);
}
@Test
public void testSimpleStartStop()
public void testSimpleStartStop() throws Exception
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
final ExtractionNamespace extractionNamespace = () -> 0;
expectScheduleAndWaitOnce(extractionNamespace);
expectEntryCloseOnce();
mockReplay();
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -169,23 +151,17 @@ public class NamespaceLookupExtractorFactoryTest
);
Assert.assertTrue(namespaceLookupExtractorFactory.start());
Assert.assertTrue(namespaceLookupExtractorFactory.close());
mockVerify();
verify(scheduler).scheduleAndWait(extractionNamespace, 60000L);
verify(entry).close();
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testStartReturnsImmediately()
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
EasyMock.expect(scheduler.schedule(EasyMock.eq(extractionNamespace))).andReturn(entry).once();
expectEntryCloseOnce();
mockReplay();
final ExtractionNamespace extractionNamespace = () -> 0;
when(scheduler.schedule(extractionNamespace)).thenReturn(entry);
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -195,29 +171,18 @@ public class NamespaceLookupExtractorFactoryTest
);
Assert.assertTrue(namespaceLookupExtractorFactory.start());
Assert.assertTrue(namespaceLookupExtractorFactory.close());
mockVerify();
}
private void expectEntryCloseOnce()
{
entry.close();
EasyMock.expectLastCall().once();
verify(scheduler).schedule(any());
verify(entry).close();
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testStartReturnsImmediatelyAndFails() throws InterruptedException
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
EasyMock.expect(scheduler.scheduleAndWait(EasyMock.eq(extractionNamespace), EasyMock.eq(1L)))
.andReturn(null).once();
mockReplay();
final ExtractionNamespace extractionNamespace = () -> 0;
when(scheduler.scheduleAndWait(extractionNamespace, 1L))
.thenReturn(null);
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -226,23 +191,16 @@ public class NamespaceLookupExtractorFactoryTest
scheduler
);
Assert.assertFalse(namespaceLookupExtractorFactory.start());
mockVerify();
verify(scheduler).scheduleAndWait(extractionNamespace, 1L);
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testSimpleStartStopStop()
public void testSimpleStartStopStop() throws Exception
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
final ExtractionNamespace extractionNamespace = () -> 0;
expectScheduleAndWaitOnce(extractionNamespace);
expectEntryCloseOnce();
mockReplay();
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -251,22 +209,17 @@ public class NamespaceLookupExtractorFactoryTest
Assert.assertTrue(namespaceLookupExtractorFactory.start());
Assert.assertTrue(namespaceLookupExtractorFactory.close());
Assert.assertTrue(namespaceLookupExtractorFactory.close());
mockVerify();
verify(entry).close();
verify(scheduler).scheduleAndWait(extractionNamespace, 60000L);
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testSimpleStartStart()
public void testSimpleStartStart() throws Exception
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
final ExtractionNamespace extractionNamespace = () -> 0;
expectScheduleAndWaitOnce(extractionNamespace);
mockReplay();
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -274,27 +227,21 @@ public class NamespaceLookupExtractorFactoryTest
);
Assert.assertTrue(namespaceLookupExtractorFactory.start());
Assert.assertTrue(namespaceLookupExtractorFactory.start());
mockVerify();
verify(scheduler).scheduleAndWait(extractionNamespace, 60000L);
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testSimpleStartGetStop()
public void testSimpleStartGetStop() throws Exception
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
final ExtractionNamespace extractionNamespace = () -> 0;
expectScheduleAndWaitOnce(extractionNamespace);
expectEntryGetCacheStateOnce(versionedCache);
expectEmptyCache();
expectVersionOnce("0");
expectEntryCloseOnce();
mockReplay();
when(entry.getCacheState()).thenReturn(versionedCache);
when(entry.getCache()).thenReturn(new HashMap<String, String>());
when(versionedCache.getCache()).thenReturn(new HashMap<>());
when(versionedCache.getVersion()).thenReturn("0");
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -304,18 +251,18 @@ public class NamespaceLookupExtractorFactoryTest
final LookupExtractor extractor = namespaceLookupExtractorFactory.get();
Assert.assertNull(extractor.apply("foo"));
Assert.assertTrue(namespaceLookupExtractorFactory.close());
mockVerify();
}
private void expectEmptyCache()
{
EasyMock.expect(entry.getCache()).andReturn(new HashMap<String, String>()).anyTimes();
EasyMock.expect(versionedCache.getCache()).andReturn(new HashMap<String, String>()).anyTimes();
verify(scheduler).scheduleAndWait(extractionNamespace, 60000L);
verify(entry).getCacheState();
verify(entry).close();
verify(versionedCache).getVersion();
verify(versionedCache, atLeastOnce()).getCache();
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testSimpleStartRacyGetDuringDelete()
public void testSimpleStartRacyGetDuringDelete() throws Exception
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@ -326,48 +273,27 @@ public class NamespaceLookupExtractorFactoryTest
}
};
expectScheduleAndWaitOnce(extractionNamespace);
expectEntryGetCacheStateOnce(CacheScheduler.NoCache.ENTRY_CLOSED);
mockReplay();
when(entry.getCacheState()).thenReturn(CacheScheduler.NoCache.ENTRY_CLOSED);
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
scheduler
);
Assert.assertTrue(namespaceLookupExtractorFactory.start());
try {
namespaceLookupExtractorFactory.get();
Assert.fail("Should have thrown ISE");
}
catch (ISE ise) {
// NOOP
}
Assert.assertThrows(ISE.class, () -> namespaceLookupExtractorFactory.get());
mockVerify();
}
private void expectEntryGetCacheStateOnce(final CacheScheduler.CacheState versionedCache)
{
EasyMock.expect(entry.getCacheState()).andReturn(versionedCache).once();
}
private IExpectationSetters<String> expectVersionOnce(String version)
{
return EasyMock.expect(versionedCache.getVersion()).andReturn(version).once();
}
private void expectFooBarCache()
{
EasyMock.expect(versionedCache.getCache()).andReturn(new HashMap<>(ImmutableMap.of("foo", "bar"))).once();
verify(scheduler).scheduleAndWait(extractionNamespace, 60000L);
verify(entry).getCacheState();
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
private void expectScheduleAndWaitOnce(ExtractionNamespace extractionNamespace)
{
try {
EasyMock.expect(scheduler.scheduleAndWait(
EasyMock.eq(extractionNamespace),
EasyMock.eq(60000L)
)).andReturn(entry).once();
when(scheduler.scheduleAndWait(
extractionNamespace,
60000L
)).thenReturn(entry);
}
catch (InterruptedException e) {
throw new AssertionError(e);
@ -376,7 +302,7 @@ public class NamespaceLookupExtractorFactoryTest
@Test
public void testStartFailsToSchedule()
public void testStartFailsToSchedule() throws Exception
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@ -387,15 +313,14 @@ public class NamespaceLookupExtractorFactoryTest
}
};
try {
EasyMock.expect(scheduler.scheduleAndWait(
EasyMock.eq(extractionNamespace),
EasyMock.eq(60000L)
)).andReturn(null).once();
when(scheduler.scheduleAndWait(
extractionNamespace,
60000L
)).thenReturn(null);
}
catch (InterruptedException e) {
throw new AssertionError(e);
}
mockReplay();
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -404,15 +329,21 @@ public class NamespaceLookupExtractorFactoryTest
Assert.assertFalse(namespaceLookupExtractorFactory.start());
// true because it never fully started
Assert.assertTrue(namespaceLookupExtractorFactory.close());
mockVerify();
verify(scheduler).scheduleAndWait(
extractionNamespace,
60000L
);
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
@Test
public void testReplaces()
{
final ExtractionNamespace en1 = PowerMock.createStrictMock(ExtractionNamespace.class), en2 = PowerMock.createStrictMock(
ExtractionNamespace.class);
PowerMock.replay(en1, en2);
final ExtractionNamespace
en1 = mock(ExtractionNamespace.class),
en2 = mock(ExtractionNamespace.class);
final NamespaceLookupExtractorFactory f1 = new NamespaceLookupExtractorFactory(
en1,
scheduler
@ -427,21 +358,15 @@ public class NamespaceLookupExtractorFactoryTest
Assert.assertFalse(f1.replaces(f1b));
Assert.assertFalse(f1b.replaces(f1));
Assert.assertFalse(f1.replaces(f1));
Assert.assertTrue(f1.replaces(EasyMock.createNiceMock(LookupExtractorFactory.class)));
PowerMock.verify(en1, en2);
Assert.assertTrue(f1.replaces(mock(LookupExtractorFactory.class)));
verifyNoInteractions(en1, en2);
}
@Test(expected = ISE.class)
public void testMustBeStarted()
{
final ExtractionNamespace extractionNamespace = new ExtractionNamespace()
{
@Override
public long getPollMs()
{
return 0;
}
};
final ExtractionNamespace extractionNamespace = () -> 0;
final NamespaceLookupExtractorFactory namespaceLookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
@ -521,7 +446,8 @@ public class NamespaceLookupExtractorFactoryTest
final String str2 = "{ \"type\": \"cachedNamespace\", \"extractionNamespace\": { \"type\": \"uri\", \"uriPrefix\": \"s3://bucket/prefix/\", \"fileRegex\": \"foo.*\\\\.gz\", \"namespaceParseSpec\": { \"format\": \"customJson\", \"keyFieldName\": \"someKey\", \"valueFieldName\": \"someVal\" }, \"pollPeriod\": \"PT5M\" } } }";
final NamespaceLookupExtractorFactory factory2 =
(NamespaceLookupExtractorFactory) mapper.readValue(str2, LookupExtractorFactory.class);
Assert.assertTrue(factory1.getCacheScheduler() == factory2.getCacheScheduler());
Assert.assertSame(factory1.getCacheScheduler(), factory2.getCacheScheduler());
}
private Injector makeInjector()
@ -529,18 +455,11 @@ public class NamespaceLookupExtractorFactoryTest
return Initialization.makeInjectorWithModules(
GuiceInjectors.makeStartupInjector(),
ImmutableList.of(
new Module()
{
@Override
public void configure(Binder binder)
{
JsonConfigProvider.bindInstance(
binder,
Key.get(DruidNode.class, Self.class),
new DruidNode("test-inject", null, false, null, null, true, false)
);
}
}
binder -> JsonConfigProvider.bindInstance(
binder,
Key.get(DruidNode.class, Self.class),
new DruidNode("test-inject", null, false, null, null, true, false)
)
)
);
}
@ -548,11 +467,9 @@ public class NamespaceLookupExtractorFactoryTest
@Test
public void testExceptionalIntrospectionHandler() throws Exception
{
final ExtractionNamespace extractionNamespace = PowerMock.createStrictMock(ExtractionNamespace.class);
EasyMock.expect(scheduler.scheduleAndWait(EasyMock.eq(extractionNamespace), EasyMock.anyLong()))
.andReturn(entry)
.once();
mockReplay();
final ExtractionNamespace extractionNamespace = mock(ExtractionNamespace.class);
when(scheduler.scheduleAndWait(eq(extractionNamespace), anyLong())).thenReturn(entry);
final LookupExtractorFactory lookupExtractorFactory = new NamespaceLookupExtractorFactory(
extractionNamespace,
scheduler
@ -563,33 +480,21 @@ public class NamespaceLookupExtractorFactoryTest
Assert.assertNotNull(handler);
final Class<? extends LookupIntrospectHandler> clazz = handler.getClass();
mockVerify();
mockReset();
EasyMock.expect(entry.getCacheState()).andReturn(CacheScheduler.NoCache.CACHE_NOT_INITIALIZED).once();
mockReplay();
verify(scheduler).scheduleAndWait(eq(extractionNamespace), anyLong());
verifyNoMoreInteractions(scheduler, entry, versionedCache);
reset(scheduler, entry, versionedCache);
when(entry.getCacheState()).thenReturn(CacheScheduler.NoCache.CACHE_NOT_INITIALIZED);
final Response response = (Response) clazz.getMethod("getVersion").invoke(handler);
Assert.assertEquals(404, response.getStatus());
verify(entry).getCacheState();
validateNotFound("getKeys", handler, clazz);
validateNotFound("getValues", handler, clazz);
validateNotFound("getMap", handler, clazz);
mockVerify();
}
private void mockReplay()
{
PowerMock.replay(scheduler, entry, versionedCache);
}
private void mockReset()
{
PowerMock.reset(scheduler, entry, versionedCache);
}
private void mockVerify()
{
PowerMock.verify(scheduler, entry, versionedCache);
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
private void validateNotFound(
@ -598,13 +503,21 @@ public class NamespaceLookupExtractorFactoryTest
Class<? extends LookupIntrospectHandler> clazz
) throws Exception
{
mockVerify();
mockReset();
expectEntryGetCacheStateOnce(versionedCache);
expectEmptyCache();
EasyMock.expect(versionedCache.getVersion()).andThrow(new ISE("some exception")).once();
mockReplay();
verifyNoMoreInteractions(scheduler, entry, versionedCache);
reset(scheduler, entry, versionedCache);
when(entry.getCacheState()).thenReturn(versionedCache);
when(entry.getCache()).thenReturn(new HashMap<String, String>());
when(versionedCache.getCache()).thenReturn(new HashMap<>());
when(versionedCache.getVersion()).thenThrow(new ISE("some exception"));
final Response response = (Response) clazz.getMethod(method).invoke(handler);
Assert.assertEquals(404, response.getStatus());
verify(entry).getCacheState();
verify(entry, atMostOnce()).getCache();
verify(versionedCache, atMostOnce()).getCache();
verify(versionedCache).getVersion();
verifyNoMoreInteractions(scheduler, entry, versionedCache);
}
}

View File

@ -136,11 +136,6 @@
<artifactId>equalsverifier</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>

View File

@ -157,26 +157,16 @@
<artifactId>hamcrest-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>

View File

@ -19,64 +19,56 @@
package org.apache.druid.indexer;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.util.List;
@RunWith(PowerMockRunner.class)
@PrepareForTest({
JobHelper.class,
IndexGeneratorJob.class
})
@PowerMockIgnore({"javax.net.ssl.*", "org.apache.logging.log4j.*"})
@SuppressStaticInitializationFor({
"org.apache.druid.indexer.HadoopDruidIndexerConfig",
"org.apache.druid.indexer.JobHelper",
"org.apache.druid.indexer.IndexGeneratorJob"
})
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class HadoopDruidIndexerJobTest
{
private HadoopDruidIndexerConfig config;
private MetadataStorageUpdaterJobHandler handler;
private HadoopDruidIndexerJob target;
@Test
public void test_run()
{
config = PowerMock.createMock(HadoopDruidIndexerConfig.class);
handler = PowerMock.createMock(MetadataStorageUpdaterJobHandler.class);
PowerMock.mockStaticNice(JobHelper.class);
PowerMock.mockStaticNice(IndexGeneratorJob.class);
config.verify();
EasyMock.expectLastCall();
EasyMock.expect(config.isUpdaterJobSpecSet()).andReturn(false).anyTimes();
config.setHadoopJobIdFileName(EasyMock.anyString());
EasyMock.expectLastCall();
JobHelper.ensurePaths(config);
EasyMock.expectLastCall();
Capture<List<Jobby>> capturedJobs = Capture.newInstance();
EasyMock.expect(JobHelper.runJobs(EasyMock.capture(capturedJobs))).andReturn(true);
EasyMock.expect(IndexGeneratorJob.getPublishedSegmentAndIndexZipFilePaths(EasyMock.anyObject())).andReturn(null);
HadoopDruidIndexerConfig config = mock(HadoopDruidIndexerConfig.class);
MetadataStorageUpdaterJobHandler handler = mock(MetadataStorageUpdaterJobHandler.class);
try (MockedStatic<JobHelper> jobHelperMock = Mockito.mockStatic(JobHelper.class)) {
try (final MockedStatic<IndexGeneratorJob> indexGeneratorJobMock = Mockito.mockStatic(IndexGeneratorJob.class)) {
when(config.isUpdaterJobSpecSet()).thenReturn(false);
jobHelperMock.when(() -> JobHelper.runJobs(any())).thenReturn(true);
indexGeneratorJobMock.when(() -> IndexGeneratorJob.getPublishedSegmentAndIndexZipFilePaths(any())).thenReturn(null);
PowerMock.replayAll();
HadoopDruidIndexerJob target = new HadoopDruidIndexerJob(config, handler);
target.run();
target = new HadoopDruidIndexerJob(config, handler);
target.run();
ArgumentCaptor<List<Jobby>> capturedJobs = ArgumentCaptor.forClass(List.class);
jobHelperMock.verify(() -> JobHelper.runJobs(capturedJobs.capture()));
List<Jobby> jobs = capturedJobs.getValue();
Assert.assertEquals(2, jobs.size());
jobs.stream().filter(job -> !(job instanceof IndexGeneratorJob)).forEach(job -> Assert.assertTrue(job.run()));
List<Jobby> jobs = capturedJobs.getValue();
Assert.assertEquals(2, jobs.size());
jobs.stream().filter(job -> !(job instanceof IndexGeneratorJob)).forEach(job -> Assert.assertTrue(job.run()));
PowerMock.verifyAll();
jobHelperMock.verify(() -> JobHelper.ensurePaths(config));
jobHelperMock.verifyNoMoreInteractions();
indexGeneratorJobMock.verify(() -> IndexGeneratorJob.getPublishedSegmentAndIndexZipFilePaths(any()));
indexGeneratorJobMock.verifyNoMoreInteractions();
verify(config).verify();
verify(config, atLeastOnce()).isUpdaterJobSpecSet();
verify(config).setHadoopJobIdFileName(null);
verifyNoMoreInteractions(config);
}
}
}
}

View File

@ -21,28 +21,18 @@ package org.apache.druid.indexer;
import com.google.common.collect.ImmutableList;
import org.apache.druid.indexer.updater.MetadataStorageUpdaterJobSpec;
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.util.List;
import java.util.stream.Collectors;
@RunWith(PowerMockRunner.class)
@PrepareForTest({
IndexGeneratorJob.class
})
@PowerMockIgnore({"javax.net.ssl.*"})
@SuppressStaticInitializationFor({
"org.apache.druid.indexer.HadoopIngestionSpec",
"org.apache.druid.indexer.HadoopDruidIndexerConfig",
"org.apache.druid.indexer.IndexGeneratorJob"
})
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class MetadataStorageUpdaterJobTest
{
private static final List<DataSegmentAndIndexZipFilePath> DATA_SEGMENT_AND_INDEX_ZIP_FILE_PATHS = ImmutableList.of(
@ -59,30 +49,39 @@ public class MetadataStorageUpdaterJobTest
@Test
public void test_run()
{
metadataUpdateSpec = PowerMock.createMock(MetadataStorageUpdaterJobSpec.class);
ioConfig = PowerMock.createMock(HadoopIOConfig.class);
spec = PowerMock.createMock(HadoopIngestionSpec.class);
config = PowerMock.createMock(HadoopDruidIndexerConfig.class);
handler = PowerMock.createMock(MetadataStorageUpdaterJobHandler.class);
PowerMock.mockStaticNice(IndexGeneratorJob.class);
metadataUpdateSpec = mock(MetadataStorageUpdaterJobSpec.class);
ioConfig = mock(HadoopIOConfig.class);
spec = mock(HadoopIngestionSpec.class);
config = mock(HadoopDruidIndexerConfig.class);
handler = mock(MetadataStorageUpdaterJobHandler.class);
EasyMock.expect(metadataUpdateSpec.getSegmentTable()).andReturn(SEGMENT_TABLE);
EasyMock.expect(ioConfig.getMetadataUpdateSpec()).andReturn(metadataUpdateSpec);
EasyMock.expect(spec.getIOConfig()).andReturn(ioConfig);
EasyMock.expect(config.getSchema()).andReturn(spec);
EasyMock.expect(IndexGeneratorJob.getPublishedSegmentAndIndexZipFilePaths(config))
.andReturn(DATA_SEGMENT_AND_INDEX_ZIP_FILE_PATHS);
handler.publishSegments(
SEGMENT_TABLE,
DATA_SEGMENT_AND_INDEX_ZIP_FILE_PATHS.stream().map(s -> s.getSegment()).collect(
Collectors.toList()), HadoopDruidIndexerConfig.JSON_MAPPER);
EasyMock.expectLastCall();
target = new MetadataStorageUpdaterJob(config, handler);
try (MockedStatic<IndexGeneratorJob> mockedStatic = Mockito.mockStatic(IndexGeneratorJob.class)) {
mockedStatic.when(() -> IndexGeneratorJob.getPublishedSegmentAndIndexZipFilePaths(config))
.thenReturn(DATA_SEGMENT_AND_INDEX_ZIP_FILE_PATHS);
PowerMock.replayAll();
target.run();
when(metadataUpdateSpec.getSegmentTable()).thenReturn(SEGMENT_TABLE);
when(ioConfig.getMetadataUpdateSpec()).thenReturn(metadataUpdateSpec);
when(spec.getIOConfig()).thenReturn(ioConfig);
when(config.getSchema()).thenReturn(spec);
PowerMock.verifyAll();
target = new MetadataStorageUpdaterJob(config, handler);
target.run();
verify(handler).publishSegments(
SEGMENT_TABLE,
DATA_SEGMENT_AND_INDEX_ZIP_FILE_PATHS.stream().map(s -> s.getSegment()).collect(
Collectors.toList()), HadoopDruidIndexerConfig.JSON_MAPPER
);
verify(metadataUpdateSpec).getSegmentTable();
verify(ioConfig).getMetadataUpdateSpec();
verify(spec).getIOConfig();
verify(config).getSchema();
mockedStatic.verify(() -> IndexGeneratorJob.getPublishedSegmentAndIndexZipFilePaths(config));
verifyNoMoreInteractions(handler, metadataUpdateSpec, ioConfig, spec, config);
}
}
}

View File

@ -121,7 +121,7 @@ public class SequenceMetadataTest
@Test
public void testPublishAnnotatedSegmentsSucceedIfDropSegmentsAndOverwriteSegmentsNullAndEmpty() throws Exception
{
Mockito.when(mockSeekableStreamIndexTaskRunner.deserializePartitionsFromMetadata(ArgumentMatchers.anyObject(), ArgumentMatchers.anyObject())).thenReturn(mockSeekableStreamEndSequenceNumbers);
Mockito.when(mockSeekableStreamIndexTaskRunner.deserializePartitionsFromMetadata(ArgumentMatchers.any(), ArgumentMatchers.any())).thenReturn(mockSeekableStreamEndSequenceNumbers);
Mockito.when(mockSeekableStreamEndSequenceNumbers.getPartitionSequenceNumberMap()).thenReturn(ImmutableMap.of());
Mockito.when(mockTaskToolbox.getTaskActionClient()).thenReturn(mockTaskActionClient);
DataSegment dataSegment = DataSegment.builder()

View File

@ -823,18 +823,9 @@ name: net.bytebuddy byte-buddy
license_category: binary
module: extensions/druid-pac4j
license_name: Apache License version 2.0
version: 1.9.10
version: 1.12.7
libraries:
- net.bytebuddy: byte-buddy
---
name: net.bytebuddy byte-buddy-agent
license_category: binary
module: extensions/druid-pac4j
license_name: Apache License version 2.0
version: 1.9.10
libraries:
- net.bytebuddy: byte-buddy-agent
---
@ -843,7 +834,7 @@ name: org.mockito mockito-core
license_category: binary
module: extensions/druid-pac4j
license_name: MIT License
version: 2.28.2
version: 4.3.1
libraries:
- org.mockito: mockito-core

26
pom.xml
View File

@ -108,8 +108,7 @@
<slf4j.version>1.7.12</slf4j.version>
<!-- If compiling with different hadoop version also modify default hadoop coordinates in TaskConfig.java -->
<hadoop.compile.version>2.8.5</hadoop.compile.version>
<mockito.version>3.8.0</mockito.version>
<powermock.version>2.0.9</powermock.version>
<mockito.version>4.3.1</mockito.version>
<aws.sdk.version>1.12.37</aws.sdk.version>
<caffeine.version>2.8.0</caffeine.version>
<jacoco.version>0.8.7</jacoco.version>
@ -924,27 +923,10 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<artifactId>mockito-bom</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>

View File

@ -76,7 +76,7 @@ public class KillAuditLogTest
);
killAuditLog = new KillAuditLog(mockAuditManager, druidCoordinatorConfig);
killAuditLog.run(mockDruidCoordinatorRuntimeParams);
Mockito.verifyZeroInteractions(mockAuditManager);
Mockito.verifyNoInteractions(mockAuditManager);
}
@Test

View File

@ -114,9 +114,9 @@ public class KillCompactionConfigTest
mockConnectorConfig
);
killCompactionConfig.run(mockDruidCoordinatorRuntimeParams);
Mockito.verifyZeroInteractions(mockSqlSegmentsMetadataManager);
Mockito.verifyZeroInteractions(mockJacksonConfigManager);
Mockito.verifyZeroInteractions(mockServiceEmitter);
Mockito.verifyNoInteractions(mockSqlSegmentsMetadataManager);
Mockito.verifyNoInteractions(mockJacksonConfigManager);
Mockito.verifyNoInteractions(mockServiceEmitter);
}
@Test
@ -199,7 +199,7 @@ public class KillCompactionConfigTest
mockConnectorConfig
);
killCompactionConfig.run(mockDruidCoordinatorRuntimeParams);
Mockito.verifyZeroInteractions(mockSqlSegmentsMetadataManager);
Mockito.verifyNoInteractions(mockSqlSegmentsMetadataManager);
final ArgumentCaptor<ServiceEventBuilder> emittedEventCaptor = ArgumentCaptor.forClass(ServiceEventBuilder.class);
Mockito.verify(mockServiceEmitter).emit(emittedEventCaptor.capture());
Assert.assertEquals(KillCompactionConfig.COUNT_METRIC, emittedEventCaptor.getValue().build(ImmutableMap.of()).toMap().get("metric"));

View File

@ -85,8 +85,8 @@ public class KillDatasourceMetadataTest
);
killDatasourceMetadata = new KillDatasourceMetadata(druidCoordinatorConfig, mockIndexerMetadataStorageCoordinator, mockMetadataSupervisorManager);
killDatasourceMetadata.run(mockDruidCoordinatorRuntimeParams);
Mockito.verifyZeroInteractions(mockIndexerMetadataStorageCoordinator);
Mockito.verifyZeroInteractions(mockMetadataSupervisorManager);
Mockito.verifyNoInteractions(mockIndexerMetadataStorageCoordinator);
Mockito.verifyNoInteractions(mockMetadataSupervisorManager);
}
@Test

View File

@ -83,7 +83,7 @@ public class KillRulesTest
);
killRules = new KillRules(druidCoordinatorConfig);
killRules.run(mockDruidCoordinatorRuntimeParams);
Mockito.verifyZeroInteractions(mockRuleManager);
Mockito.verifyNoInteractions(mockRuleManager);
}
@Test

View File

@ -76,7 +76,7 @@ public class KillSupervisorsTest
);
killSupervisors = new KillSupervisors(druidCoordinatorConfig, mockMetadataSupervisorManager);
killSupervisors.run(mockDruidCoordinatorRuntimeParams);
Mockito.verifyZeroInteractions(mockMetadataSupervisorManager);
Mockito.verifyNoInteractions(mockMetadataSupervisorManager);
}
@Test