jdk-24/test/jdk/java/nio/jni/NewDirectByteBuffer.java
2023-01-23 17:12:49 +00:00

144 lines
5.6 KiB
Java

/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicReference;
import jdk.internal.misc.Unsafe;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/*
* @test
* @bug 8299684
* @summary Unit test for the JNI function NewDirectByteBuffer
* @requires (sun.arch.data.model == "64" & os.maxMemory >= 8g)
* @modules java.base/jdk.internal.misc
* @run junit/othervm/native NewDirectByteBuffer
*/
public class NewDirectByteBuffer {
private static final Unsafe UNSAFE;
static {
System.loadLibrary("NewDirectByteBuffer");
UNSAFE = Unsafe.getUnsafe();
}
private static final void checkBuffer(ByteBuffer buf, long capacity) {
// Verify that the JNI function returns the correct capacity
assertEquals(capacity, getDirectByteBufferCapacity(buf),
"GetDirectBufferCapacity returned unexpected value");
// Verify that the initial state values are correct
assertTrue(buf.isDirect(), "Buffer is not direct");
assertFalse(buf.hasArray(), "Buffer has an array");
if (capacity > 0) {
assertTrue(buf.hasRemaining(), "Buffer has no remaining values");
}
assertFalse(buf.isReadOnly(), "Buffer s read-only");
assertEquals(capacity, buf.capacity(),
"Buffer::capacity returned unexpected value");
assertEquals(0L, buf.position(),
"Buffer::position returned unexpected value");
assertEquals(capacity, buf.limit(),
"Buffer::limit returned unexpected value");
// Verify that the various state mutators work correctly
int halfPos = buf.capacity()/2;
buf.position(halfPos);
assertEquals(halfPos, buf.position(),
"Position not set to halfPos");
assertEquals(buf.capacity() - halfPos, buf.remaining(),
"Remaining not capacity - halfPos");
buf.mark();
int twoThirdsPos = 2*(buf.capacity()/3);
buf.position(twoThirdsPos);
assertEquals(twoThirdsPos, buf.position(),
"Position not set to twoThirdsPos");
assertEquals(buf.capacity() - twoThirdsPos, buf.remaining(),
"Remaining != capacity - twoThirdsPos");
buf.reset();
assertEquals(halfPos, buf.position(),
"Buffer not reset to halfPos");
buf.limit(twoThirdsPos);
assertEquals(twoThirdsPos, buf.limit(),
"Limit not set to twoThirdsPos");
assertEquals(twoThirdsPos - halfPos, buf.remaining(),
"Remaining != twoThirdsPos - halfPos");
buf.position(twoThirdsPos);
assertFalse(buf.hasRemaining(), "Buffer has remaining values");
}
@ParameterizedTest
@ValueSource(longs = {0L, 1L, (long)Integer.MAX_VALUE/2,
(long)Integer.MAX_VALUE - 1, (long)Integer.MAX_VALUE})
void legalCapacities(long capacity) {
long addr;
try {
addr = UNSAFE.allocateMemory(capacity);
} catch (OutOfMemoryError ignore) {
System.err.println("legalCapacities( " + capacity
+ ") test skipped due to insufficient memory");
return;
}
try {
ByteBuffer buf = newDirectByteBuffer(addr, capacity);
assertEquals(addr, getDirectBufferAddress(buf),
"GetDirectBufferAddress does not return supplied address");
checkBuffer(buf, capacity);
} finally {
UNSAFE.freeMemory(addr);
}
}
@ParameterizedTest
@ValueSource(longs = {Long.MIN_VALUE, (long)Integer.MIN_VALUE - 1L, -1L,
(long)Integer.MAX_VALUE + 1L, 3_000_000_000L, 5_000_000_000L,
Long.MAX_VALUE})
void illegalCapacities(long capacity) {
assertThrows(IllegalArgumentException.class, () -> {
long addr = UNSAFE.allocateMemory(1);
try {
ByteBuffer buf = newDirectByteBuffer(addr, capacity);
} finally {
UNSAFE.freeMemory(addr);
}
});
}
// See libNewDirectByteBuffer.c for implementations.
private static native ByteBuffer newDirectByteBuffer(long addr, long capacity);
private static native long getDirectByteBufferCapacity(ByteBuffer buf);
private static native long getDirectBufferAddress(ByteBuffer buf);
}