Update OsTest#test_socket_setSockoptTimeval_effective
After setting the receive timeout, read-back the value that the kernel
has and use that for determining if the timeout is too early.
Bug: 216667550
Test: atest CtsLibcoreTestCases:libcore.android.system.OsTest#test_socket_setSockoptTimeval_effective
Change-Id: I91f729f8637bf8cea819a28bca89332c12c46bcb
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
index ce67896..a52d5d6 100755
--- a/luni/src/test/java/libcore/android/system/OsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -1569,29 +1569,38 @@
@Test
public void test_socket_setSockoptTimeval_effective() throws Exception {
- // b/176104885 Older devices can return a few ms early, add a tolerance for them
- long timeoutTolerance = kernelIsAtLeast(3, 18) ? 0 : 10;
-
- int timeoutValueMillis = 250;
- int allowedTimeoutMillis = 3000;
+ final int TIMEOUT_VALUE_MILLIS = 250;
+ final int ALLOWED_TIMEOUT_MILLIS = 3000;
+ final int ROUNDING_ERROR_MILLIS = 10;
FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
try {
- StructTimeval tv = StructTimeval.fromMillis(timeoutValueMillis);
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, tv);
- Os.bind(fd, InetAddress.getByName("::1"), 0);
+ // Configure the receive timeout.
+ StructTimeval tvTarget = StructTimeval.fromMillis(TIMEOUT_VALUE_MILLIS);
+ Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, tvTarget);
+ // Check the system's idea of the receive timeout. Our requested timeout may
+ // be rounded by the kernel (b/176104885, b/216667550).
+ StructTimeval tvActual = Os.getsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO);
+ // The kernel may round the requested value based on the HZ setting. We allow up to
+ // 10ms difference.
+ assertTrue(
+ "Returned incorrect timeout:" + tvTarget,
+ Math.abs(tvTarget.toMillis() - tvActual.toMillis()) <= ROUNDING_ERROR_MILLIS);
+
+ // Bind socket and wait for data (and timeout).
+ Os.bind(fd, InetAddress.getByName("::1"), 0);
byte[] request = new byte[1];
long startTime = System.nanoTime();
expectException(() -> Os.read(fd, request, 0, request.length),
ErrnoException.class, EAGAIN, "Expected timeout");
long durationMillis = Duration.ofNanos(System.nanoTime() - startTime).toMillis();
- assertTrue("Timeout of " + timeoutValueMillis + "ms returned after "
+ assertTrue("Timeout of " + tvActual.toMillis() + "ms returned after "
+ durationMillis +"ms",
- durationMillis >= timeoutValueMillis - timeoutTolerance);
- assertTrue("Timeout of " + timeoutValueMillis + "ms failed to return within "
- + allowedTimeoutMillis + "ms",
- durationMillis < allowedTimeoutMillis);
+ durationMillis >= tvActual.toMillis());
+ assertTrue("Timeout of " + TIMEOUT_VALUE_MILLIS + "ms failed to return within "
+ + ALLOWED_TIMEOUT_MILLIS + "ms",
+ durationMillis < ALLOWED_TIMEOUT_MILLIS);
} finally {
Os.close(fd);
}