Replace securemock with mock-maker (test support), update Mockito to 3.12.4 (#1332)

Signed-off-by: Andriy Redko <andriy.redko@aiven.io>
This commit is contained in:
Andriy Redko 2021-10-10 14:18:54 -04:00 committed by GitHub
parent 3665daf5d0
commit e9635d6bfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 240 additions and 83 deletions

View File

@ -36,9 +36,9 @@ httpasyncclient = 4.1.4
commonslogging = 1.1.3
commonscodec = 1.13
hamcrest = 2.1
securemock = 1.2
mockito = 1.9.5
objenesis = 1.0
mockito = 3.12.4
objenesis = 3.2
bytebuddy = 1.11.13
# benchmark dependencies
jmh = 1.19

View File

@ -53,6 +53,7 @@ dependencies {
testImplementation "org.hamcrest:hamcrest:${versions.hamcrest}"
testImplementation "org.mockito:mockito-core:${versions.mockito}"
testImplementation "org.objenesis:objenesis:${versions.objenesis}"
testImplementation "net.bytebuddy:byte-buddy:${versions.bytebuddy}"
}
tasks.withType(CheckForbiddenApis).configureEach {

View File

@ -101,6 +101,7 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -137,7 +138,7 @@ public class RestClientSingleHostTests extends RestClientTestCase {
static CloseableHttpAsyncClient mockHttpClient(final ExecutorService exec) {
CloseableHttpAsyncClient httpClient = mock(CloseableHttpAsyncClient.class);
when(httpClient.<HttpResponse>execute(any(HttpAsyncRequestProducer.class), any(HttpAsyncResponseConsumer.class),
any(HttpClientContext.class), any(FutureCallback.class))).thenAnswer((Answer<Future<HttpResponse>>) invocationOnMock -> {
any(HttpClientContext.class), nullable(FutureCallback.class))).thenAnswer((Answer<Future<HttpResponse>>) invocationOnMock -> {
final HttpAsyncRequestProducer requestProducer = (HttpAsyncRequestProducer) invocationOnMock.getArguments()[0];
final FutureCallback<HttpResponse> futureCallback =
(FutureCallback<HttpResponse>) invocationOnMock.getArguments()[3];
@ -215,7 +216,7 @@ public class RestClientSingleHostTests extends RestClientTestCase {
for (String httpMethod : getHttpMethods()) {
HttpUriRequest expectedRequest = performRandomRequest(httpMethod);
verify(httpClient, times(++times)).<HttpResponse>execute(requestArgumentCaptor.capture(),
any(HttpAsyncResponseConsumer.class), any(HttpClientContext.class), any(FutureCallback.class));
any(HttpAsyncResponseConsumer.class), any(HttpClientContext.class), nullable(FutureCallback.class));
HttpUriRequest actualRequest = (HttpUriRequest)requestArgumentCaptor.getValue().generateRequest();
assertEquals(expectedRequest.getURI(), actualRequest.getURI());
assertEquals(expectedRequest.getClass(), actualRequest.getClass());

View File

@ -49,6 +49,7 @@ dependencies {
testImplementation "junit:junit:${versions.junit}"
testImplementation "org.mockito:mockito-core:${versions.mockito}"
testImplementation "org.objenesis:objenesis:${versions.objenesis}"
testImplementation "net.bytebuddy:byte-buddy:${versions.bytebuddy}"
}
tasks.named('forbiddenApisMain').configure {

View File

@ -12,8 +12,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.mock.orig.Mockito;
import org.junit.Before;
import org.mockito.Mockito;
import org.opensearch.cli.MockTerminal;
import org.opensearch.common.collect.Tuple;
import org.opensearch.common.settings.Settings;

View File

@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.isNull;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.doAnswer;
@ -192,7 +192,7 @@ public class NioSelectorTests extends OpenSearchTestCase {
public void testSelectorClosedExceptionIsNotCaughtWhileRunning() throws IOException {
boolean closedSelectorExceptionCaught = false;
when(rawSelector.select(anyInt())).thenThrow(new ClosedSelectorException());
when(rawSelector.select(anyLong())).thenThrow(new ClosedSelectorException());
try {
this.selector.singleLoop();
} catch (ClosedSelectorException e) {
@ -205,7 +205,7 @@ public class NioSelectorTests extends OpenSearchTestCase {
public void testIOExceptionWhileSelect() throws IOException {
IOException ioException = new IOException();
when(rawSelector.select(anyInt())).thenThrow(ioException);
when(rawSelector.select(anyLong())).thenThrow(ioException);
this.selector.singleLoop();

View File

@ -41,6 +41,7 @@ import org.apache.lucene.index.NoMergePolicy;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.mockito.Mockito;
import org.opensearch.LegacyESVersion;
import org.opensearch.Version;
import org.opensearch.cluster.metadata.IndexMetadata;
@ -56,7 +57,6 @@ import org.opensearch.index.mapper.Mapper;
import org.opensearch.index.mapper.ParseContext;
import org.opensearch.index.query.QueryShardContext;
import org.opensearch.index.query.TermQueryBuilder;
import org.elasticsearch.mock.orig.Mockito;
import org.opensearch.search.SearchModule;
import org.opensearch.search.aggregations.support.CoreValuesSourceType;
import org.opensearch.test.OpenSearchTestCase;

View File

@ -34,7 +34,7 @@
//// These are mock objects and test management that we allow test framework libs
//// to provide on our behalf. But tests themselves cannot do this stuff!
grant codeBase "${codebase.securemock}" {
grant codeBase "${codebase.mockito-core}" {
// needed to access ReflectionFactory (see below)
permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
// needed for reflection in ibm jdk
@ -44,6 +44,27 @@ grant codeBase "${codebase.securemock}" {
// needed for spy interception, etc
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.lang.RuntimePermission "getClassLoader";
};
grant codeBase "${codebase.objenesis}" {
permission java.lang.RuntimePermission "reflectionFactoryAccess";
permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};
grant codeBase "${codebase.byte-buddy}" {
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "net.bytebuddy.createJavaDispatcher";
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.lang.reflect.ReflectPermission "newProxyInPackage.net.bytebuddy.utility";
permission java.lang.reflect.ReflectPermission "newProxyInPackage.net.bytebuddy.dynamic.loading";
permission java.lang.reflect.ReflectPermission "newProxyInPackage.net.bytebuddy.description.type";
permission java.lang.reflect.ReflectPermission "newProxyInPackage.net.bytebuddy.description.method";
};
grant codeBase "${codebase.lucene-test-framework}" {

View File

@ -79,8 +79,6 @@ import org.opensearch.transport.TransportResponseHandler;
import org.opensearch.transport.TransportService;
import org.junit.Before;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
import java.util.Collections;
@ -125,13 +123,9 @@ public class TransportBulkActionIngestTests extends OpenSearchTestCase {
ThreadPool threadPool;
/** Arguments to callbacks we want to capture, but which require generics, so we must use @Captor */
@Captor
ArgumentCaptor<BiConsumer<Integer, Exception>> failureHandler;
@Captor
ArgumentCaptor<BiConsumer<Thread, Exception>> completionHandler;
@Captor
ArgumentCaptor<TransportResponseHandler<BulkResponse>> remoteResponseHandler;
@Captor
ArgumentCaptor<Iterable<DocWriteRequest<?>>> bulkDocsItr;
/** The actual action we want to test, with real indexing mocked */
@ -199,7 +193,12 @@ public class TransportBulkActionIngestTests extends OpenSearchTestCase {
threadPool = mock(ThreadPool.class);
final ExecutorService direct = OpenSearchExecutors.newDirectExecutorService();
when(threadPool.executor(anyString())).thenReturn(direct);
MockitoAnnotations.initMocks(this);
bulkDocsItr = ArgumentCaptor.forClass(Iterable.class);
failureHandler = ArgumentCaptor.forClass(BiConsumer.class);
completionHandler = ArgumentCaptor.forClass(BiConsumer.class);
remoteResponseHandler = ArgumentCaptor.forClass(TransportResponseHandler.class);
// setup services that will be called by action
transportService = mock(TransportService.class);
clusterService = mock(ClusterService.class);
@ -672,6 +671,7 @@ public class TransportBulkActionIngestTests extends OpenSearchTestCase {
}));
assertEquals("pipeline2", indexRequest.getPipeline());
verify(ingestService).executeBulkRequest(eq(1), bulkDocsItr.capture(), failureHandler.capture(),
completionHandler.capture(), any(), eq(Names.WRITE));
}

View File

@ -77,6 +77,7 @@ import static java.util.Collections.emptySet;
import static org.opensearch.common.UUIDs.randomBase64UUID;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
@ -144,13 +145,13 @@ public class TransportMultiGetActionTests extends OpenSearchTestCase {
when(index2ShardIterator.shardId()).thenReturn(new ShardId(index2, randomInt()));
final OperationRouting operationRouting = mock(OperationRouting.class);
when(operationRouting.getShards(eq(clusterState), eq(index1.getName()), anyString(), anyString(), anyString()))
.thenReturn(index1ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index1.getName()), anyString(), anyString()))
when(operationRouting.getShards(eq(clusterState), eq(index1.getName()), anyString(), nullable(String.class),
nullable(String.class))).thenReturn(index1ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index1.getName()), nullable(String.class), nullable(String.class)))
.thenReturn(new ShardId(index1, randomInt()));
when(operationRouting.getShards(eq(clusterState), eq(index2.getName()), anyString(), anyString(), anyString()))
.thenReturn(index2ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index2.getName()), anyString(), anyString()))
when(operationRouting.getShards(eq(clusterState), eq(index2.getName()), anyString(), nullable(String.class),
nullable(String.class))).thenReturn(index2ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index2.getName()), nullable(String.class), nullable(String.class)))
.thenReturn(new ShardId(index2, randomInt()));
clusterService = mock(ClusterService.class);

View File

@ -80,6 +80,7 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -145,13 +146,13 @@ public class TransportMultiTermVectorsActionTests extends OpenSearchTestCase {
when(index2ShardIterator.shardId()).thenReturn(new ShardId(index2, randomInt()));
final OperationRouting operationRouting = mock(OperationRouting.class);
when(operationRouting.getShards(eq(clusterState), eq(index1.getName()), anyString(), anyString(), anyString()))
.thenReturn(index1ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index1.getName()), anyString(), anyString()))
when(operationRouting.getShards(eq(clusterState), eq(index1.getName()), anyString(), nullable(String.class),
nullable(String.class))).thenReturn(index1ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index1.getName()), nullable(String.class), nullable(String.class)))
.thenReturn(new ShardId(index1, randomInt()));
when(operationRouting.getShards(eq(clusterState), eq(index2.getName()), anyString(), anyString(), anyString()))
.thenReturn(index2ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index2.getName()), anyString(), anyString()))
when(operationRouting.getShards(eq(clusterState), eq(index2.getName()), anyString(), nullable(String.class),
nullable(String.class))).thenReturn(index2ShardIterator);
when(operationRouting.shardId(eq(clusterState), eq(index2.getName()), nullable(String.class), nullable(String.class)))
.thenReturn(new ShardId(index2, randomInt()));
clusterService = mock(ClusterService.class);

View File

@ -35,9 +35,9 @@ package org.opensearch.common.settings;
import org.opensearch.cluster.ClusterState;
import org.opensearch.cluster.ClusterStateUpdateTask;
import org.opensearch.cluster.service.ClusterService;
import org.elasticsearch.mock.orig.Mockito;
import org.opensearch.test.OpenSearchTestCase;
import org.junit.Before;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import java.util.Arrays;

View File

@ -70,7 +70,6 @@ import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
@ -420,6 +419,6 @@ public class SeedHostsResolverTests extends OpenSearchTestCase {
assertThat(transportAddresses, hasSize(1)); // only one of the two is valid and will be used
assertThat(transportAddresses.get(0).getAddress(), equalTo("127.0.0.1"));
assertThat(transportAddresses.get(0).getPort(), equalTo(9301));
verify(logger).warn(eq("failed to resolve host [127.0.0.1:9300:9300]"), Matchers.any(ExecutionException.class));
verify(logger).warn(eq("failed to resolve host [127.0.0.1:9300:9300]"), Matchers.any(IllegalArgumentException.class));
}
}

View File

@ -52,11 +52,11 @@ import org.opensearch.transport.TransportService;
import java.util.Collections;
import static org.elasticsearch.mock.orig.Mockito.never;
import static org.elasticsearch.mock.orig.Mockito.when;
import static org.opensearch.test.ClusterServiceUtils.createClusterService;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class GlobalCheckpointSyncActionTests extends OpenSearchTestCase {

View File

@ -58,11 +58,11 @@ import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.elasticsearch.mock.orig.Mockito.when;
import static org.opensearch.test.ClusterServiceUtils.createClusterService;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class RetentionLeaseBackgroundSyncActionTests extends OpenSearchTestCase {

View File

@ -58,11 +58,11 @@ import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import static java.util.Collections.emptyMap;
import static org.elasticsearch.mock.orig.Mockito.when;
import static org.opensearch.test.ClusterServiceUtils.createClusterService;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class RetentionLeaseSyncActionTests extends OpenSearchTestCase {

View File

@ -66,12 +66,11 @@ import java.util.concurrent.atomic.AtomicLong;
import static org.opensearch.index.seqno.SequenceNumbers.NO_OPS_PERFORMED;
import static org.opensearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.hamcrest.Matchers.any;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.instanceOf;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
@ -646,7 +645,7 @@ public class GlobalCheckpointListenersTests extends OpenSearchTestCase {
doAnswer(invocationOnMock -> {
latch.countDown();
return null;
}).when(mockLogger).warn(argThat(any(String.class)), argThat(any(RuntimeException.class)));
}).when(mockLogger).warn(any(String.class), any(RuntimeException.class));
final GlobalCheckpointListeners globalCheckpointListeners =
new GlobalCheckpointListeners(shardId, scheduler, mockLogger);
final TimeValue timeout = TimeValue.timeValueMillis(randomIntBetween(1, 50));

View File

@ -160,7 +160,7 @@ import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.stub;
import static org.mockito.Mockito.when;
@LuceneTestCase.SuppressFileSystems("ExtrasFS")
public class TranslogTests extends OpenSearchTestCase {
@ -411,7 +411,7 @@ public class TranslogTests extends OpenSearchTestCase {
long period = randomLongBetween(10000, 1000000);
periods[numberOfReaders] = period;
TranslogWriter w = mock(TranslogWriter.class);
stub(w.getLastModifiedTime()).toReturn(fixedTime - period);
when(w.getLastModifiedTime()).thenReturn(fixedTime - period);
assertThat(Translog.findEarliestLastModifiedAge(fixedTime, new ArrayList<>(), w), equalTo(period));
for (int i = 0; i < numberOfReaders; i++) {
@ -420,7 +420,7 @@ public class TranslogTests extends OpenSearchTestCase {
List<TranslogReader> readers = new ArrayList<>();
for (long l : periods) {
TranslogReader r = mock(TranslogReader.class);
stub(r.getLastModifiedTime()).toReturn(fixedTime - l);
when(r.getLastModifiedTime()).thenReturn(fixedTime - l);
readers.add(r);
}
assertThat(Translog.findEarliestLastModifiedAge(fixedTime, readers, w), equalTo

View File

@ -77,7 +77,6 @@ import org.opensearch.test.OpenSearchTestCase;
import org.opensearch.test.MockLogAppender;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.threadpool.ThreadPool.Names;
import org.hamcrest.CustomTypeSafeMatcher;
import org.junit.Before;
import org.mockito.ArgumentMatcher;
import org.mockito.invocation.InvocationOnMock;
@ -724,19 +723,8 @@ public class IngestServiceTests extends OpenSearchTestCase {
ingestService.executeBulkRequest(bulkRequest.numberOfActions(), bulkRequest.requests(), failureHandler,
completionHandler, indexReq -> {}, Names.WRITE);
verify(failureHandler, times(1)).accept(
argThat(new CustomTypeSafeMatcher<Integer>("failure handler was not called with the expected arguments") {
@Override
protected boolean matchesSafely(Integer item) {
return item == 2;
}
}),
argThat(new CustomTypeSafeMatcher<IllegalArgumentException>("failure handler was not called with the expected arguments") {
@Override
protected boolean matchesSafely(IllegalArgumentException iae) {
return "pipeline with id [does_not_exist] does not exist".equals(iae.getMessage());
}
})
argThat((Integer item) -> item == 2),
argThat((IllegalArgumentException iae) -> "pipeline with id [does_not_exist] does not exist".equals(iae.getMessage()))
);
verify(completionHandler, times(1)).accept(Thread.currentThread(), null);
}
@ -995,12 +983,9 @@ public class IngestServiceTests extends OpenSearchTestCase {
ingestService.executeBulkRequest(numRequest, bulkRequest.requests(), requestItemErrorHandler, completionHandler, indexReq -> {},
Names.WRITE);
verify(requestItemErrorHandler, times(numIndexRequests)).accept(anyInt(), argThat(new ArgumentMatcher<Exception>() {
@Override
public boolean matches(final Object o) {
return ((Exception)o).getCause().equals(error);
}
}));
verify(requestItemErrorHandler, times(numIndexRequests)).accept(anyInt(),
argThat(o -> o.getCause().equals(error)));
verify(completionHandler, times(1)).accept(Thread.currentThread(), null);
}
@ -1499,7 +1484,7 @@ public class IngestServiceTests extends OpenSearchTestCase {
return processor;
}
private class IngestDocumentMatcher extends ArgumentMatcher<IngestDocument> {
private class IngestDocumentMatcher implements ArgumentMatcher<IngestDocument> {
private final IngestDocument ingestDocument;
@ -1512,13 +1497,8 @@ public class IngestServiceTests extends OpenSearchTestCase {
}
@Override
public boolean matches(Object o) {
if (o.getClass() == IngestDocument.class) {
IngestDocument otherIngestDocument = (IngestDocument) o;
//ingest metadata will not be the same (timestamp differs every time)
return Objects.equals(ingestDocument.getSourceAndMetadata(), otherIngestDocument.getSourceAndMetadata());
}
return false;
public boolean matches(IngestDocument o) {
return Objects.equals(ingestDocument.getSourceAndMetadata(), o.getSourceAndMetadata());
}
}

View File

@ -55,9 +55,9 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import static org.elasticsearch.mock.orig.Mockito.when;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class RestRecoveryActionTests extends OpenSearchTestCase {

View File

@ -85,6 +85,7 @@ import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -122,7 +123,8 @@ public class DefaultSearchContextTests extends OpenSearchTestCase {
when(indexCache.query()).thenReturn(queryCache);
when(indexService.cache()).thenReturn(indexCache);
QueryShardContext queryShardContext = mock(QueryShardContext.class);
when(indexService.newQueryShardContext(eq(shardId.id()), anyObject(), anyObject(), anyString())).thenReturn(queryShardContext);
when(indexService.newQueryShardContext(eq(shardId.id()), anyObject(), anyObject(),
nullable(String.class))).thenReturn(queryShardContext);
MapperService mapperService = mock(MapperService.class);
when(mapperService.hasNested()).thenReturn(randomBoolean());
when(indexService.mapperService()).thenReturn(mapperService);
@ -267,7 +269,8 @@ public class DefaultSearchContextTests extends OpenSearchTestCase {
IndexService indexService = mock(IndexService.class);
QueryShardContext queryShardContext = mock(QueryShardContext.class);
when(indexService.newQueryShardContext(eq(shardId.id()), anyObject(), anyObject(), anyString())).thenReturn(queryShardContext);
when(indexService.newQueryShardContext(eq(shardId.id()), anyObject(), anyObject(),
nullable(String.class))).thenReturn(queryShardContext);
BigArrays bigArrays = new MockBigArrays(new MockPageCacheRecycler(Settings.EMPTY), new NoneCircuitBreakerService());

View File

@ -45,7 +45,9 @@ dependencies {
api "org.apache.lucene:lucene-codecs:${versions.lucene}"
api "commons-logging:commons-logging:${versions.commonslogging}"
api "commons-codec:commons-codec:${versions.commonscodec}"
api "org.elasticsearch:securemock:${versions.securemock}"
api "org.mockito:mockito-core:${versions.mockito}"
api "net.bytebuddy:byte-buddy:${versions.bytebuddy}"
api "org.objenesis:objenesis:${versions.objenesis}"
}
compileJava.options.compilerArgs -= '-Xlint:cast'
@ -73,15 +75,14 @@ thirdPartyAudit.ignoreMissingClasses(
'org.apache.log4j.Level',
'org.apache.log4j.Logger',
'org.apache.log4j.Priority',
// TODO - OpenSearch remove this missing classes. Issue: https://github.com/opensearch-project/OpenSearch/issues/420
'org.apache.tools.ant.BuildException',
'org.apache.tools.ant.DirectoryScanner',
'org.apache.tools.ant.Task',
'org.apache.tools.ant.types.FileSet',
'org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher',
'org.opentest4j.AssertionFailedError',
'net.bytebuddy.agent.ByteBuddyAgent'
)
// TODO - OpenSearch remove this violation. Issue: https://github.com/opensearch-project/OpenSearch/issues/420
thirdPartyAudit.ignoreViolations(
'org.objenesis.instantiator.sun.UnsafeFactoryInstantiator'
'org.objenesis.instantiator.sun.UnsafeFactoryInstantiator',
'org.objenesis.instantiator.util.UnsafeUtils'
)
test {

View File

@ -44,6 +44,7 @@ import org.opensearch.common.io.PathUtils;
import org.opensearch.common.network.IfConfig;
import org.opensearch.common.network.NetworkAddress;
import org.opensearch.common.settings.Settings;
import org.opensearch.mockito.plugin.PriviledgedMockMaker;
import org.opensearch.plugins.PluginInfo;
import org.opensearch.secure_sm.SecureSM;
import org.junit.Assert;
@ -151,8 +152,8 @@ public class BootstrapForTesting {
addClassCodebase(codebases,"opensearch", "org.opensearch.plugins.PluginsService");
if (System.getProperty("tests.gradle") == null) {
// intellij and eclipse don't package our internal libs, so we need to set the codebases for them manually
addClassCodebase(codebases,"plugin-classloader", "org.opensearch.plugins.ExtendedPluginsClassLoader");
addClassCodebase(codebases,"opensearch-nio", "org.opensearch.nio.ChannelFactory");
addClassCodebase(codebases, "plugin-classloader", "org.opensearch.plugins.ExtendedPluginsClassLoader");
addClassCodebase(codebases, "opensearch-nio", "org.opensearch.nio.ChannelFactory");
addClassCodebase(codebases, "opensearch-secure-sm", "org.opensearch.secure_sm.SecureSM");
addClassCodebase(codebases, "opensearch-rest-client", "org.opensearch.client.RestClient");
}
@ -165,6 +166,8 @@ public class BootstrapForTesting {
return opensearchPolicy.implies(domain, permission) || testFramework.implies(domain, permission);
}
});
// Create access control context for mocking
PriviledgedMockMaker.createAccessControlContext();
System.setSecurityManager(SecureSM.createTestSecureSM(getTrustedHosts()));
Security.selfTest();

View File

@ -0,0 +1,145 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
package org.opensearch.mockito.plugin;
import org.mockito.Incubating;
import org.mockito.MockedConstruction;
import org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker;
import org.mockito.internal.util.reflection.LenientCopyTool;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
import org.mockito.plugins.MockMaker;
import org.opensearch.common.SuppressForbidden;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.DomainCombiner;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
/**
* Mockito plugin which wraps the Mockito calls into priviledged execution blocks and respects
* SecurityManager presence.
*/
@SuppressForbidden(reason = "allow URL#getFile() to be used in tests")
public class PriviledgedMockMaker implements MockMaker {
private static AccessControlContext context;
private final ByteBuddyMockMaker delegate;
/**
* Create dedicated AccessControlContext to use the Mockito protection domain (test only)
* so to relax the security constraints for the test cases which rely on mocks. This plugin
* wraps the mock/spy creation into priviledged action using the custom access control context
* since Mockito does not support SecurityManager out of the box. The method has to be called by
* test framework before the SecurityManager is being set, otherwise additional permissions have
* to be granted to the caller:
*
* permission java.security.Permission "createAccessControlContext"
*
*/
public static void createAccessControlContext() {
// This combiner, if bound to an access control context, will unconditionally
// substitute the call chain protection domains with the 'mockito-core' one if it
// is present. The security checks are relaxed intentionally to trust mocking
// implementation if it is part of the call chain.
final DomainCombiner combiner = (current, assigned) -> Arrays
.stream(current)
.filter(pd ->
pd
.getCodeSource()
.getLocation()
.getFile()
.contains("mockito-core") /* check mockito-core only */)
.findAny()
.map(pd -> new ProtectionDomain[] { pd })
.orElse(current);
// Bind combiner to an access control context (the combiner stateless and shareable)
final AccessControlContext wrapper = new AccessControlContext(AccessController.getContext(), combiner);
// Create new access control context with dedicated combiner
context = AccessController.doPrivileged(
(PrivilegedAction<AccessControlContext>) AccessController::getContext,
wrapper);
}
/**
* Construct an instance of the priviledged mock maker using ByteBuddyMockMaker under the hood.
*/
public PriviledgedMockMaker() {
delegate = AccessController.doPrivileged(
(PrivilegedAction<ByteBuddyMockMaker>) () -> new ByteBuddyMockMaker(),
context);
}
@SuppressWarnings("rawtypes")
@Override
public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler) {
return AccessController.doPrivileged(
(PrivilegedAction<T>) () -> delegate.createMock(settings, handler),
context);
}
@SuppressWarnings("rawtypes")
@Override
public <T> Optional<T> createSpy(MockCreationSettings<T> settings, MockHandler handler, T object) {
// The ByteBuddyMockMaker does not implement createSpy and relies on Mockito's fallback
return AccessController.doPrivileged(
(PrivilegedAction<Optional<T> >) () -> {
T instance = delegate.createMock(settings, handler);
new LenientCopyTool().copyToMock(object, instance);
return Optional.of(instance);
},
context);
}
@SuppressWarnings("rawtypes")
@Override
public MockHandler getHandler(Object mock) {
return delegate.getHandler(mock);
}
@SuppressWarnings("rawtypes")
@Override
public void resetMock(Object mock, MockHandler newHandler, MockCreationSettings settings) {
AccessController.doPrivileged(
(PrivilegedAction<Void>) () -> {
delegate.resetMock(mock, newHandler, settings);
return null;
}, context);
}
@Override
@Incubating
public TypeMockability isTypeMockable(Class<?> type) {
return delegate.isTypeMockable(type);
}
@SuppressWarnings("rawtypes")
@Override
public <T> StaticMockControl<T> createStaticMock(Class<T> type, MockCreationSettings<T> settings, MockHandler handler) {
return delegate.createStaticMock(type, settings, handler);
}
@Override
public <T> ConstructionMockControl<T> createConstructionMock(Class<T> type,
Function<MockedConstruction.Context, MockCreationSettings<T>> settingsFactory,
Function<MockedConstruction.Context, MockHandler<T>> handlerFactory,
MockedConstruction.MockInitializer<T> mockInitializer) {
return delegate.createConstructionMock(type, settingsFactory, handlerFactory, mockInitializer);
}
@Override
public void clearAllCaches() {
delegate.clearAllCaches();
}
}

View File

@ -0,0 +1 @@
org.opensearch.mockito.plugin.PriviledgedMockMaker