blob: bdec625c8eb357227c30dbd230cf5a1fa2196383 [file] [log] [blame]
package jnr.posix;
import jnr.constants.platform.AddressFamily;
import jnr.constants.platform.PosixFadvise;
import jnr.constants.platform.OpenFlags;
import jnr.constants.platform.Sock;
import jnr.constants.platform.SocketLevel;
import jnr.constants.platform.SocketOption;
import jnr.ffi.Platform;
import jnr.posix.util.ConditionalTestRule;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import static jnr.posix.LinuxIoPrio.*;
public class LinuxPOSIXTest {
@ClassRule
public static RunningOnLinux rule = new RunningOnLinux();
private static Linux linuxPOSIX = null;
@BeforeClass
public static void setUpClass() throws Exception {
POSIX posix = POSIXFactory.getNativePOSIX();
if (posix instanceof Linux) {
linuxPOSIX = (Linux) posix;
}
}
/**
* Tests that IO priority can be set to a thread and that it doesn't change priority set on
* another thread
* @throws InterruptedException
* @throws ExecutionException
*/
@Test
public void ioprioThreadedTest() throws InterruptedException, ExecutionException {
linuxPOSIX.ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4));
Future<Integer> threadPriorityFuture = Executors.newFixedThreadPool(1).submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
linuxPOSIX.ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 7));
return linuxPOSIX.ioprio_get(IOPRIO_WHO_PROCESS, 0);
}
});
int threadPriority = threadPriorityFuture.get().intValue();
Assert.assertEquals(7, IOPRIO_PRIO_DATA(threadPriority));
Assert.assertEquals(IOPRIO_CLASS_IDLE, IOPRIO_PRIO_CLASS(threadPriority));
Assert.assertEquals(4, IOPRIO_PRIO_DATA(linuxPOSIX.ioprio_get(IOPRIO_WHO_PROCESS, 0)));
Assert.assertEquals(IOPRIO_CLASS_BE, IOPRIO_PRIO_CLASS(linuxPOSIX.ioprio_get(IOPRIO_WHO_PROCESS, 0)));
}
@Test
public void testMessageHdrMultipleControl() {
if (jnr.posix.util.Platform.IS_WINDOWS) {
return;
}
int[] fds = {0, 0};
int ret = linuxPOSIX.socketpair(AddressFamily.AF_UNIX.intValue(),
Sock.SOCK_STREAM.intValue(),
0,
fds);
String data = "twoControlMessages";
byte[] dataBytes = data.getBytes();
Assert.assertTrue(ret >= 0);
Assert.assertTrue(fds[0] > 0);
Assert.assertTrue(fds[1] > 0);
ByteBuffer buf = ByteBuffer.allocate(4);
buf.order(ByteOrder.nativeOrder());
buf.putInt(1).flip();
ret = linuxPOSIX.libc().setsockopt(fds[1],
SocketLevel.SOL_SOCKET.intValue(),
SocketOption.SO_PASSCRED.intValue(),
buf,
buf.remaining());
Assert.assertTrue(ret >= 0);
MsgHdr outMessage = linuxPOSIX.allocateMsgHdr();
ByteBuffer[] outIov = new ByteBuffer[1];
outIov[0] = ByteBuffer.allocateDirect(dataBytes.length);
outIov[0].put(dataBytes);
outIov[0].flip();
outMessage.setIov(outIov);
CmsgHdr[] outControl = outMessage.allocateControls(new int[]{4});
outControl[0].setLevel(SocketLevel.SOL_SOCKET.intValue());
outControl[0].setType(0x01);
ByteBuffer fdBuf = ByteBuffer.allocateDirect(4);
fdBuf.order(ByteOrder.nativeOrder());
fdBuf.putInt(0, fds[0]);
outControl[0].setData(fdBuf);
int sendStatus = linuxPOSIX.sendmsg(fds[0], outMessage, 0);
if (sendStatus == -1) {
String sendmsgError = "Error with sendmsg: " + linuxPOSIX.strerror(linuxPOSIX.errno());
Assert.fail(sendmsgError);
return;
}
Assert.assertEquals(dataBytes.length, sendStatus);
// ----------------
MsgHdr inMessage = linuxPOSIX.allocateMsgHdr();
ByteBuffer[] inIov = new ByteBuffer[1];
inIov[0] = ByteBuffer.allocateDirect(1024);
inMessage.setIov(inIov);
inMessage.allocateControls(new int[]{4, 12});
int recvStatus = linuxPOSIX.recvmsg(fds[1], inMessage, 0);
Assert.assertEquals(dataBytes.length, recvStatus);
Assert.assertEquals(2, inMessage.getControls().length);
CmsgHdr[] controls = inMessage.getControls();
for (int x = 0; x < controls.length; x++) {
validateCmsghdr(controls[x]);
}
}
private void validateCmsghdr(CmsgHdr control) {
if (control.getLevel() == SocketLevel.SOL_SOCKET.intValue()
&& control.getType() == 0x01) {
// Passing a FD
ByteBuffer inFdBuf = control.getData();
inFdBuf.order(ByteOrder.nativeOrder());
int fd = inFdBuf.getInt();
Assert.assertTrue(fd != 0);
} else if (control.getLevel() == SocketLevel.SOL_SOCKET.intValue()
&& control.getType() == 0x02) {
//Credentials
ByteBuffer data = control.getData();
data.order(ByteOrder.nativeOrder());
int got_pid = data.getInt();
int got_uid = data.getInt();
int got_gid = data.getInt();
Assert.assertEquals(linuxPOSIX.getpid(), got_pid);
Assert.assertEquals(linuxPOSIX.getuid(), got_uid);
Assert.assertEquals(linuxPOSIX.getgid(), got_gid);
} else {
Assert.fail("Unable to determine cmsghdr type");
}
}
@Test
public void testPosixFadvise() throws Throwable {
File file = File.createTempFile("posix_fadvise", null);
int fd = linuxPOSIX.open(file.getAbsolutePath(), OpenFlags.O_RDWR.intValue(), 0444);
Assert.assertEquals(0, linuxPOSIX.posix_fadvise(fd, 0, 0, PosixFadvise.POSIX_FADV_SEQUENTIAL));
Assert.assertEquals(0, linuxPOSIX.posix_fadvise(fd, 0, 0, PosixFadvise.POSIX_FADV_RANDOM));
Assert.assertEquals(0, linuxPOSIX.posix_fadvise(fd, 0, 0, PosixFadvise.POSIX_FADV_NOREUSE));
Assert.assertEquals(0, linuxPOSIX.posix_fadvise(fd, 0, 0, PosixFadvise.POSIX_FADV_WILLNEED));
Assert.assertEquals(0, linuxPOSIX.posix_fadvise(fd, 0, 0, PosixFadvise.POSIX_FADV_DONTNEED));
Assert.assertEquals(0, linuxPOSIX.posix_fadvise(fd, 0, 0, PosixFadvise.POSIX_FADV_NORMAL)); // normal last to reset it
linuxPOSIX.close(fd);
}
}
class RunningOnLinux extends ConditionalTestRule {
public boolean isSatisfied() {
return jnr.ffi.Platform.getNativePlatform().getOS().equals(Platform.OS.LINUX);
}
}