mirror of https://github.com/apache/lucene.git
LUCENE-10330: Make the mmap directory tests fail by default, if unmapping does not work (#556)
Co-authored-by: Dawid Weiss <dawid.weiss@gmail.com>
This commit is contained in:
parent
8f99c12113
commit
b4d29ccddb
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
apply plugin: 'java-library'
|
||||
|
||||
description = 'Module tests for :lucene:core'
|
||||
|
||||
dependencies {
|
||||
moduleTestImplementation project(':lucene:core')
|
||||
moduleTestImplementation("junit:junit", {
|
||||
exclude group: "org.hamcrest"
|
||||
})
|
||||
moduleTestImplementation "org.hamcrest:hamcrest"
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** Test module for {@code org.apache.lucene.core}. */
|
||||
@SuppressWarnings({"requires-automatic"})
|
||||
module org.apache.lucene.core.tests {
|
||||
requires org.apache.lucene.core;
|
||||
requires junit;
|
||||
|
||||
exports org.apache.lucene.core.tests;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.lucene.core.tests;
|
||||
|
||||
import org.apache.lucene.store.MMapDirectory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestMMap {
|
||||
@Test
|
||||
public void testUnmapSupported() throws Exception {
|
||||
final Module module = MMapDirectory.class.getModule();
|
||||
Assert.assertTrue("Lucene Core is not loaded as module", module.isNamed());
|
||||
Assert.assertTrue(
|
||||
"Lucene Core can't read 'jdk.unsupported' module",
|
||||
module.getLayer().findModule("jdk.unsupported").map(module::canRead).orElse(false));
|
||||
|
||||
// check that MMapDirectory can unmap by running the autodetection logic:
|
||||
Assert.assertTrue(MMapDirectory.UNMAP_NOT_SUPPORTED_REASON, MMapDirectory.UNMAP_SUPPORTED);
|
||||
}
|
||||
}
|
|
@ -346,9 +346,7 @@ public class MMapDirectory extends FSDirectory {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(
|
||||
reason =
|
||||
"Needs access to private APIs in DirectBuffer, sun.misc.Cleaner, and sun.misc.Unsafe to enable hack")
|
||||
@SuppressForbidden(reason = "Needs access to sun.misc.Unsafe to enable hack")
|
||||
private static Object unmapHackImpl() {
|
||||
final Lookup lookup = lookup();
|
||||
try {
|
||||
|
@ -363,29 +361,31 @@ public class MMapDirectory extends FSDirectory {
|
|||
final Field f = unsafeClass.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
final Object theUnsafe = f.get(null);
|
||||
return newBufferCleaner(ByteBuffer.class, unmapper.bindTo(theUnsafe));
|
||||
return newBufferCleaner(unmapper.bindTo(theUnsafe));
|
||||
} catch (SecurityException se) {
|
||||
return "Unmapping is not supported, because not all required permissions are given to the Lucene JAR file: "
|
||||
+ se
|
||||
+ " [Please grant at least the following permissions: RuntimePermission(\"accessClassInPackage.sun.misc\") "
|
||||
+ " and ReflectPermission(\"suppressAccessChecks\")]";
|
||||
} catch (ReflectiveOperationException | RuntimeException e) {
|
||||
final Module module = MMapDirectory.class.getModule();
|
||||
final ModuleLayer layer = module.getLayer();
|
||||
// classpath / unnamed module has no layer, so we need to check:
|
||||
if (layer != null
|
||||
&& layer.findModule("jdk.unsupported").map(module::canRead).orElse(false) == false) {
|
||||
return "Unmapping is not supported, because Lucene cannot read 'jdk.unsupported' module.";
|
||||
}
|
||||
return "Unmapping is not supported on this platform, because internal Java APIs are not compatible with this Lucene version: "
|
||||
+ e;
|
||||
}
|
||||
}
|
||||
|
||||
private static BufferCleaner newBufferCleaner(
|
||||
final Class<?> unmappableBufferClass, final MethodHandle unmapper) {
|
||||
private static BufferCleaner newBufferCleaner(final MethodHandle unmapper) {
|
||||
assert Objects.equals(methodType(void.class, ByteBuffer.class), unmapper.type());
|
||||
return (String resourceDescription, ByteBuffer buffer) -> {
|
||||
if (!buffer.isDirect()) {
|
||||
throw new IllegalArgumentException("unmapping only works with direct buffers");
|
||||
}
|
||||
if (!unmappableBufferClass.isInstance(buffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"buffer is not an instance of " + unmappableBufferClass.getName());
|
||||
}
|
||||
final Throwable error =
|
||||
AccessController.doPrivileged(
|
||||
(PrivilegedAction<Throwable>)
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
|
||||
/** Tests MMapDirectory */
|
||||
|
@ -34,10 +35,9 @@ public class TestMmapDirectory extends BaseDirectoryTestCase {
|
|||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
assumeTrue(MMapDirectory.UNMAP_NOT_SUPPORTED_REASON, MMapDirectory.UNMAP_SUPPORTED);
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
assertTrue(MMapDirectory.UNMAP_NOT_SUPPORTED_REASON, MMapDirectory.UNMAP_SUPPORTED);
|
||||
}
|
||||
|
||||
@Ignore(
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.lucene.store;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
* Tests MMapDirectory's MultiMMapIndexInput
|
||||
|
@ -33,10 +34,9 @@ public class TestMultiMMap extends BaseChunkedDirectoryTestCase {
|
|||
return new MMapDirectory(path, maxChunkSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
assumeTrue(MMapDirectory.UNMAP_NOT_SUPPORTED_REASON, MMapDirectory.UNMAP_SUPPORTED);
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
assertTrue(MMapDirectory.UNMAP_NOT_SUPPORTED_REASON, MMapDirectory.UNMAP_SUPPORTED);
|
||||
}
|
||||
|
||||
// TODO: can we improve ByteBuffersDirectory (without overhead) and move these clone safety tests
|
||||
|
|
|
@ -41,6 +41,7 @@ include "lucene:benchmark"
|
|||
include "lucene:classification"
|
||||
include "lucene:codecs"
|
||||
include "lucene:core"
|
||||
include "lucene:core.tests"
|
||||
include "lucene:demo"
|
||||
include "lucene:distribution"
|
||||
include "lucene:distribution.tests"
|
||||
|
|
Loading…
Reference in New Issue