Merge "Move CtsLibcoreOjTestCases to group presubmit-large"
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 92bbc66..2623a51 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -595,7 +595,6 @@
"nist-pkix-tests",
"slf4j-jdk14",
"sqlite-jdbc",
- "tzdata-testing",
"truth-prebuilt-jar",
],
@@ -1019,6 +1018,9 @@
// avoid introducing compile time cycles.
java_library {
name: "art.module.api.annotations.for.system.modules",
+ visibility: [
+ "//art/libartservice",
+ ],
srcs: [
":api_surface_annotation_files",
],
diff --git a/NativeCode.bp b/NativeCode.bp
index c93e214..5bfb49b 100644
--- a/NativeCode.bp
+++ b/NativeCode.bp
@@ -206,13 +206,6 @@
"libnativehelper",
],
- cflags: [
- // -DANDROID_LINK_SHARED_ICU4C to enable access to the full ICU4C.
- // See external/icu/android_icu4c/include/uconfig_local.h
- // for more information.
- "-DANDROID_LINK_SHARED_ICU4C",
- ],
-
strip: {
keep_symbols: true,
},
diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java
index 031ddfa..e72d707 100644
--- a/luni/src/main/java/libcore/icu/ICU.java
+++ b/luni/src/main/java/libcore/icu/ICU.java
@@ -405,6 +405,17 @@
}
/**
+ * {@link java.text.SimpleDateFormat} does not handle some date symbols, e.g. 'B' / 'b',
+ * and simply ignore the symbol in formatting. Instead, we should avoid exposing the symbol
+ * entirely in all public APIs, e.g. {@link java.text.SimpleDateFormat#toPattern()},
+ * and thus we use a heuristic algorithm to remove the symbol. See http://b/174804526.
+ * See {@link #transformIcuDateTimePattern(String)} for documentation about the implementation.
+ */
+ public static String transformIcuDateTimePattern_forJavaText(String pattern) {
+ return transformIcuDateTimePattern(pattern);
+ }
+
+ /**
* Rewrite the date/time pattern coming ICU to be consumed by libcore classes.
* It's an ideal place to rewrite the pattern entirely when multiple symbols not digested
* by libcore need to be removed/processed. Rewriting in single place could be more efficient
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index c255720..04170a6 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -413,21 +413,27 @@
// libcore's java.text supports Gregorian calendar only.
ExtendedCalendar extendedCalendar = ICU.getExtendedCalendar(locale, "gregorian");
- fullTimeFormat = extendedCalendar.getDateTimePattern(
+ fullTimeFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.NONE, android.icu.text.DateFormat.FULL);
- longTimeFormat = extendedCalendar.getDateTimePattern(
+ longTimeFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.NONE, android.icu.text.DateFormat.LONG);
- mediumTimeFormat = extendedCalendar.getDateTimePattern(
+ mediumTimeFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.NONE, android.icu.text.DateFormat. MEDIUM);
- shortTimeFormat = extendedCalendar.getDateTimePattern(
+ shortTimeFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.NONE, android.icu.text.DateFormat.SHORT);
- fullDateFormat = extendedCalendar.getDateTimePattern(
+ fullDateFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.FULL, android.icu.text.DateFormat.NONE);
- longDateFormat = extendedCalendar.getDateTimePattern(
+ longDateFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.LONG, android.icu.text.DateFormat.NONE);
- mediumDateFormat = extendedCalendar.getDateTimePattern(
+ mediumDateFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.MEDIUM, android.icu.text.DateFormat.NONE);
- shortDateFormat = extendedCalendar.getDateTimePattern(
+ shortDateFormat = getDateTimeFormatString(extendedCalendar,
android.icu.text.DateFormat.SHORT, android.icu.text.DateFormat.NONE);
}
+
+ private static String getDateTimeFormatString(ExtendedCalendar extendedCalendar,
+ int dateStyle, int timeStyle) {
+ return ICU.transformIcuDateTimePattern_forJavaText(
+ extendedCalendar.getDateTimePattern(dateStyle, timeStyle));
+ }
}
diff --git a/luni/src/main/java/libcore/util/FP16.java b/luni/src/main/java/libcore/util/FP16.java
index 602e1d4..78a3c19 100644
--- a/luni/src/main/java/libcore/util/FP16.java
+++ b/luni/src/main/java/libcore/util/FP16.java
@@ -158,18 +158,45 @@
@libcore.api.CorePlatformApi
public static final short POSITIVE_ZERO = (short) 0x0000;
+ /**
+ * The offset to shift by to obtain the sign bit.
+ */
@libcore.api.CorePlatformApi
public static final int SIGN_SHIFT = 15;
+
+ /**
+ * The offset to shift by to obtain the exponent bits.
+ */
@libcore.api.CorePlatformApi
public static final int EXPONENT_SHIFT = 10;
+
+ /**
+ * The bitmask to AND a number with to obtain the sign bit.
+ */
@libcore.api.CorePlatformApi
public static final int SIGN_MASK = 0x8000;
+
+ /**
+ * The bitmask to AND a number shifted by {@link #EXPONENT_SHIFT} right, to obtain exponent bits.
+ */
@libcore.api.CorePlatformApi
public static final int SHIFTED_EXPONENT_MASK = 0x1f;
+
+ /**
+ * The bitmask to AND a number with to obtain significand bits.
+ */
@libcore.api.CorePlatformApi
public static final int SIGNIFICAND_MASK = 0x3ff;
+
+ /**
+ * The bitmask to AND with to obtain exponent and significand bits.
+ */
@libcore.api.CorePlatformApi
public static final int EXPONENT_SIGNIFICAND_MASK = 0x7fff;
+
+ /**
+ * The offset of the exponent from the actual value.
+ */
@libcore.api.CorePlatformApi
public static final int EXPONENT_BIAS = 15;
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
index def9c5d..6d1a135 100644
--- a/luni/src/test/java/libcore/android/system/OsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -49,21 +49,34 @@
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import junit.framework.TestCase;
-
import libcore.io.IoUtils;
import libcore.testing.io.TestIoUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
import static android.system.OsConstants.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
-public class OsTest extends TestCase {
+@RunWith(JUnit4.class)
+public class OsTest {
+ @Test
public void testIsSocket() throws Exception {
File f = new File("/dev/null");
FileInputStream fis = new FileInputStream(f);
@@ -75,6 +88,7 @@
s.close();
}
+ @Test
public void testFcntlInt() throws Exception {
File f = File.createTempFile("OsTest", "tst");
FileInputStream fis = null;
@@ -89,6 +103,7 @@
}
}
+ @Test
public void testFcntlInt_udpSocket() throws Exception {
final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
try {
@@ -106,6 +121,7 @@
}
}
+ @Test
public void testFcntlInt_invalidCmd() throws Exception {
final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
try {
@@ -119,7 +135,8 @@
}
}
- public void testFcntlInt_nullFd() throws Exception {
+ @Test
+ public void testFcntlInt_nullFd() {
try {
Os.fcntlInt(null, F_SETFL, O_NONBLOCK);
fail("Expected failure due to null file descriptor");
@@ -128,17 +145,20 @@
}
}
+ @Test
public void testUnixDomainSockets_in_file_system() throws Exception {
String path = System.getProperty("java.io.tmpdir") + "/test_unix_socket";
new File(path).delete();
checkUnixDomainSocket(UnixSocketAddress.createFileSystem(path), false);
}
+ @Test
public void testUnixDomainSocket_abstract_name() throws Exception {
// Linux treats a sun_path starting with a NUL byte as an abstract name. See unix(7).
checkUnixDomainSocket(UnixSocketAddress.createAbstract("/abstract_name_unix_socket"), true);
}
+ @Test
public void testUnixDomainSocket_unnamed() throws Exception {
final FileDescriptor fd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
// unix(7) says an unbound socket is unnamed.
@@ -172,8 +192,8 @@
byte[] request = new byte[256];
Os.read(clientFd, request, 0, request.length);
- String s = new String(request, "UTF-8");
- byte[] response = s.toUpperCase(Locale.ROOT).getBytes("UTF-8");
+ String s = new String(request, StandardCharsets.UTF_8);
+ byte[] response = s.toUpperCase(Locale.ROOT).getBytes(StandardCharsets.UTF_8);
Os.write(clientFd, response, 0, response.length);
Os.close(clientFd);
@@ -191,13 +211,13 @@
String string = "hello, world!";
- byte[] request = string.getBytes("UTF-8");
+ byte[] request = string.getBytes(StandardCharsets.UTF_8);
assertEquals(request.length, Os.write(clientFd, request, 0, request.length));
byte[] response = new byte[request.length];
assertEquals(response.length, Os.read(clientFd, response, 0, response.length));
- assertEquals(string.toUpperCase(Locale.ROOT), new String(response, "UTF-8"));
+ assertEquals(string.toUpperCase(Locale.ROOT), new String(response, StandardCharsets.UTF_8));
Os.close(clientFd);
}
@@ -223,16 +243,17 @@
checkNoName((UnixSocketAddress) Os.getsockname(fd));
}
- public void test_strsignal() throws Exception {
+ @Test
+ public void test_strsignal() {
assertEquals("Killed", Os.strsignal(9));
assertEquals("Unknown signal -1", Os.strsignal(-1));
}
+ @Test
public void test_byteBufferPositions_write_pwrite() throws Exception {
FileOutputStream fos = new FileOutputStream(new File("/dev/null"));
FileDescriptor fd = fos.getFD();
- final byte[] contents = new String("goodbye, cruel world")
- .getBytes(StandardCharsets.US_ASCII);
+ final byte[] contents = "goodbye, cruel world".getBytes(StandardCharsets.US_ASCII);
ByteBuffer byteBuffer = ByteBuffer.wrap(contents);
byteBuffer.position(0);
@@ -258,6 +279,7 @@
fos.close();
}
+ @Test
public void test_byteBufferPositions_read_pread() throws Exception {
FileInputStream fis = new FileInputStream(new File("/dev/zero"));
FileDescriptor fd = fis.getFD();
@@ -286,7 +308,7 @@
fis.close();
}
- static void checkByteBufferPositions_sendto_recvfrom(
+ private static void checkByteBufferPositions_sendto_recvfrom(
int family, InetAddress loopback) throws Exception {
final FileDescriptor serverFd = Os.socket(family, SOCK_STREAM, 0);
Os.bind(serverFd, loopback, 0);
@@ -294,29 +316,27 @@
InetSocketAddress address = (InetSocketAddress) Os.getsockname(serverFd);
- final Thread server = new Thread(new Runnable() {
- public void run() {
- try {
- InetSocketAddress peerAddress = new InetSocketAddress();
- FileDescriptor clientFd = Os.accept(serverFd, peerAddress);
+ final Thread server = new Thread(() -> {
+ try {
+ InetSocketAddress peerAddress = new InetSocketAddress();
+ FileDescriptor clientFd = Os.accept(serverFd, peerAddress);
- // Attempt to receive a maximum of 24 bytes from the client, and then
- // close the connection.
- ByteBuffer buffer = ByteBuffer.allocate(16);
- int received = Os.recvfrom(clientFd, buffer, 0, null);
- assertTrue(received > 0);
- assertEquals(received, buffer.position());
+ // Attempt to receive a maximum of 24 bytes from the client, and then
+ // close the connection.
+ ByteBuffer buffer = ByteBuffer.allocate(16);
+ int received = Os.recvfrom(clientFd, buffer, 0, null);
+ assertTrue(received > 0);
+ assertEquals(received, buffer.position());
- ByteBuffer buffer2 = ByteBuffer.allocate(16);
- buffer2.position(8);
- received = Os.recvfrom(clientFd, buffer2, 0, null);
- assertTrue(received > 0);
- assertEquals(received + 8, buffer.position());
+ ByteBuffer buffer2 = ByteBuffer.allocate(16);
+ buffer2.position(8);
+ received = Os.recvfrom(clientFd, buffer2, 0, null);
+ assertTrue(received > 0);
+ assertEquals(received + 8, buffer.position());
- Os.close(clientFd);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
+ Os.close(clientFd);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
}
});
@@ -346,9 +366,8 @@
Os.close(clientFd);
}
- interface ExceptionalRunnable {
-
- public void run() throws Exception;
+ private interface ExceptionalRunnable {
+ void run() throws Exception;
}
/**
@@ -377,7 +396,7 @@
}
private static void expectBindException(FileDescriptor socket, SocketAddress addr,
- Class exClass, Integer expectedErrno) {
+ Class<? extends Exception> exClass, Integer expectedErrno) {
String msg = String.format("bind(%s, %s)", socket, addr);
expectException(() -> {
Os.bind(socket, addr);
@@ -385,7 +404,7 @@
}
private static void expectConnectException(FileDescriptor socket, SocketAddress addr,
- Class exClass, Integer expectedErrno) {
+ Class<? extends Exception> exClass, Integer expectedErrno) {
String msg = String.format("connect(%s, %s)", socket, addr);
expectException(() -> {
Os.connect(socket, addr);
@@ -393,13 +412,13 @@
}
private static void expectSendtoException(FileDescriptor socket, SocketAddress addr,
- Class exClass, Integer expectedErrno) {
+ Integer expectedErrno) {
String msg = String.format("sendto(%s, %s)", socket, addr);
byte[] packet = new byte[42];
expectException(() -> {
Os.sendto(socket, packet, 0, packet.length, 0, addr);
},
- exClass, expectedErrno, msg);
+ ErrnoException.class, expectedErrno, msg);
}
private static void expectBindConnectSendtoSuccess(FileDescriptor socket, String socketDesc,
@@ -424,7 +443,7 @@
assertEquals(addrISA.getAddress(), socknameISA.getAddress());
assertEquals(0, addrISA.getPort());
- assertFalse(0 == socknameISA.getPort());
+ assertNotEquals(0, socknameISA.getPort());
addr = socknameISA;
}
@@ -434,8 +453,9 @@
Os.sendto(socket, packet, 0, packet.length, 0, addr);
// UNIX and IP sockets return different errors for this operation, so we can't check
// errno.
- expectSendtoException(socket, null, ErrnoException.class, null);
- expectSendtoException(null, null, ErrnoException.class, EBADF);
+ expectSendtoException(socket, null, null);
+ expectSendtoException(null, null, EBADF);
+ expectSendtoException(null, addr, EBADF);
// Expect that connect throws when any of its arguments are null.
expectConnectException(null, addr, ErrnoException.class, EBADF);
@@ -514,6 +534,7 @@
return Os.socket(AF_UNIX, SOCK_DGRAM, 0);
}
+ @Test
public void testCrossFamilyBindConnectSendto() throws Exception {
SocketAddress addrIpv4 = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0);
SocketAddress addrIpv6 = new InetSocketAddress(InetAddress.getByName("::1"), 0);
@@ -539,6 +560,7 @@
expectBindConnectSendtoSuccess(makeUnixSocket(), "unix", addrUnix);
}
+ @Test
public void testUnknownSocketAddressSubclass() throws Exception {
class MySocketAddress extends SocketAddress {
@@ -577,6 +599,7 @@
}
}
+ @Test
public void test_NetlinkSocket() throws Exception {
FileDescriptor nlSocket = Os.socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
try {
@@ -599,8 +622,10 @@
// This test is excluded from CTS via the knownfailures.txt because it requires extra
// permissions not available in CTS. To run it you have to use an -eng build and use a tool like
// vogar that runs the Android runtime as a privileged user.
+ @Test
public void test_PacketSocketAddress() throws Exception {
NetworkInterface lo = NetworkInterface.getByName("lo");
+ assertNotNull(lo);
FileDescriptor fd = Os.socket(AF_PACKET, SOCK_DGRAM, ETH_P_IPV6);
PacketSocketAddress addr =
new PacketSocketAddress(ETH_P_IPV6, lo.getIndex(), null /* sll_addr */);
@@ -614,6 +639,7 @@
// The loopback address is ETH_ALEN bytes long and is all zeros.
// http://lxr.free-electrons.com/source/drivers/net/loopback.c?v=3.10#L167
+ assertNotNull(bound.sll_addr);
assertEquals(6, bound.sll_addr.length);
for (int i = 0; i < 6; i++) {
assertEquals(0, bound.sll_addr[i]);
@@ -665,16 +691,16 @@
private static byte[] getIPv6AddressBytesAtOffset(byte[] packet, int offsetIndex) {
byte[] address = new byte[16];
- for (int i = 0; i < 16; i++) {
- address[i] = packet[i + offsetIndex];
- }
+ System.arraycopy(packet, offsetIndex, address, 0, 16);
return address;
}
+ @Test
public void test_byteBufferPositions_sendto_recvfrom_af_inet() throws Exception {
checkByteBufferPositions_sendto_recvfrom(AF_INET, InetAddress.getByName("127.0.0.1"));
}
+ @Test
public void test_byteBufferPositions_sendto_recvfrom_af_inet6() throws Exception {
checkByteBufferPositions_sendto_recvfrom(AF_INET6, InetAddress.getByName("::1"));
}
@@ -687,7 +713,8 @@
InetSocketAddress to = ((InetSocketAddress) Os.getsockname(recvFd));
FileDescriptor sendFd = Os.socket(family, SOCK_DGRAM, 0);
- byte[] msg = ("Hello, I'm going to a socket address: " + to.toString()).getBytes("UTF-8");
+ byte[] msg = ("Hello, I'm going to a socket address: " + to.toString()).getBytes(
+ StandardCharsets.UTF_8);
int len = msg.length;
assertEquals(len, Os.sendto(sendFd, msg, 0, len, 0, to));
@@ -697,14 +724,17 @@
assertEquals(loopback, from.getAddress());
}
+ @Test
public void test_sendtoSocketAddress_af_inet() throws Exception {
checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
}
+ @Test
public void test_sendtoSocketAddress_af_inet6() throws Exception {
checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
}
+ @Test
public void test_socketFamilies() throws Exception {
FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
Os.bind(fd, InetAddress.getByName("::"), 0);
@@ -729,11 +759,6 @@
}
}
- private static void assertArrayEquals(byte[] expected, byte[] actual) {
- assertTrue("Expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual),
- Arrays.equals(expected, actual));
- }
-
private static void checkSocketPing(FileDescriptor fd, InetAddress to, byte[] packet,
byte type, byte responseType, boolean useSendto) throws Exception {
int len = packet.length;
@@ -755,12 +780,13 @@
assertEquals(received[5], (byte) (icmpId & 0xff));
received = Arrays.copyOf(received, len);
- received[0] = (byte) type;
+ received[0] = type;
received[2] = received[3] = 0; // Checksum.
received[4] = received[5] = 0; // ICMP ID.
assertArrayEquals(packet, received);
}
+ @Test
public void test_socketPing() throws Exception {
final byte ICMP_ECHO = 8, ICMP_ECHOREPLY = 0;
final byte ICMPV6_ECHO_REQUEST = (byte) 128, ICMPV6_ECHO_REPLY = (byte) 129;
@@ -779,6 +805,7 @@
checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false);
}
+ @Test
public void test_Ipv4Fallback() throws Exception {
// This number of iterations gives a ~60% chance of creating the conditions that caused
// http://b/23088314 without making test times too long. On a hammerhead running MRZ37C
@@ -796,6 +823,7 @@
}
}
+ @Test
public void test_unlink() throws Exception {
File f = File.createTempFile("OsTest", "tst");
assertTrue(f.exists());
@@ -811,6 +839,7 @@
}
// b/27294715
+ @Test
public void test_recvfrom_concurrentShutdown() throws Exception {
final FileDescriptor serverFd = Os.socket(AF_INET, SOCK_DGRAM, 0);
Os.bind(serverFd, InetAddress.getByName("127.0.0.1"), 0);
@@ -818,22 +847,20 @@
StructTimeval tv = StructTimeval.fromMillis(4000);
Os.setsockoptTimeval(serverFd, SOL_SOCKET, SO_RCVTIMEO, tv);
- final AtomicReference<Exception> killerThreadException = new AtomicReference<Exception>(
- null);
- final Thread killer = new Thread(new Runnable() {
- public void run() {
+ final AtomicReference<Exception> killerThreadException = new AtomicReference<>(
+ null);
+ final Thread killer = new Thread(() -> {
+ try {
+ Thread.sleep(2000);
try {
- Thread.sleep(2000);
- try {
- Os.shutdown(serverFd, SHUT_RDWR);
- } catch (ErrnoException expected) {
- if (OsConstants.ENOTCONN != expected.errno) {
- killerThreadException.set(expected);
- }
+ Os.shutdown(serverFd, SHUT_RDWR);
+ } catch (ErrnoException expected) {
+ if (OsConstants.ENOTCONN != expected.errno) {
+ killerThreadException.set(expected);
}
- } catch (Exception ex) {
- killerThreadException.set(ex);
}
+ } catch (Exception ex) {
+ killerThreadException.set(ex);
}
});
killer.start();
@@ -841,13 +868,14 @@
ByteBuffer buffer = ByteBuffer.allocate(16);
InetSocketAddress srcAddress = new InetSocketAddress();
int received = Os.recvfrom(serverFd, buffer, 0, srcAddress);
- assertTrue(received == 0);
+ assertEquals(0, received);
Os.close(serverFd);
killer.join();
assertNull(killerThreadException.get());
}
+ @Test
public void test_xattr() throws Exception {
final String NAME_TEST = "user.meow";
@@ -899,6 +927,7 @@
}
}
+ @Test
public void test_xattr_NPE() throws Exception {
File file = File.createTempFile("xattr", "test");
final String path = file.getAbsolutePath();
@@ -954,7 +983,8 @@
}
}
- public void test_xattr_Errno() throws Exception {
+ @Test
+ public void test_xattr_Errno() {
final String NAME_TEST = "user.meow";
final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
@@ -1016,6 +1046,7 @@
}
}
+ @Test
public void test_realpath() throws Exception {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
// This is a chicken and egg problem. We have no way of knowing whether
@@ -1046,7 +1077,7 @@
}
}
- private int[] getKernelVersion() throws Exception {
+ private int[] getKernelVersion() {
// Example:
// 4.9.29-g958411d --> 4.9
String release = Os.uname().release;
@@ -1055,14 +1086,15 @@
return new int[]{ Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) };
}
- private boolean kernelIsAtLeast(int major, int minor) throws Exception {
+ private boolean kernelIsAtLeast(int major, int minor) {
int[] version = getKernelVersion();
return version[0] > major || (version[0] == major && version[1] >= minor);
}
+ @Test
public void test_socket_udpGro_setAndGet() throws Exception {
// UDP GRO not required to be enabled on kernels prior to 5.4
- if (!kernelIsAtLeast(5, 4)) return;
+ assumeTrue(kernelIsAtLeast(5, 4));
final FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, 0);
try {
@@ -1074,9 +1106,10 @@
}
}
+ @Test
public void test_socket_udpGso_set() throws Exception {
// UDP GSO not required to be enabled on kernels prior to 4.19.
- if (!kernelIsAtLeast(4, 19)) return;
+ assumeTrue(kernelIsAtLeast(4, 19));
final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
try {
@@ -1094,6 +1127,7 @@
* Tests that TCP_USER_TIMEOUT can be set on a TCP socket, but doesn't test
* that it behaves as expected.
*/
+ @Test
public void test_socket_tcpUserTimeout_setAndGet() throws Exception {
final FileDescriptor fd = Os.socket(AF_INET, SOCK_STREAM, 0);
try {
@@ -1114,6 +1148,7 @@
}
}
+ @Test
public void test_socket_tcpUserTimeout_doesNotWorkOnDatagramSocket() throws Exception {
final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
try {
@@ -1127,6 +1162,7 @@
}
}
+ @Test
public void test_socket_sockoptTimeval_readWrite() throws Exception {
FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
try {
@@ -1148,7 +1184,11 @@
}
}
+ @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;
@@ -1163,11 +1203,9 @@
expectException(() -> Os.read(fd, request, 0, request.length),
ErrnoException.class, EAGAIN, "Expected timeout");
long durationMillis = Duration.ofNanos(System.nanoTime() - startTime).toMillis();
- // TODO(b/176104885): Sometimes returns 1 msec early. It's unclear that's correct.
- // We haven't seen this on modern devices, and allow it for now. Needs investigation.
assertTrue("Timeout of " + timeoutValueMillis + "ms returned after "
+ durationMillis +"ms",
- durationMillis >= timeoutValueMillis - 1);
+ durationMillis >= timeoutValueMillis - timeoutTolerance);
assertTrue("Timeout of " + timeoutValueMillis + "ms failed to return within "
+ allowedTimeoutMillis + "ms",
durationMillis < allowedTimeoutMillis);
@@ -1176,13 +1214,15 @@
}
}
- public void test_socket_setSockoptTimeval_nullFd() throws Exception {
+ @Test
+ public void test_socket_setSockoptTimeval_nullFd() {
StructTimeval tv = StructTimeval.fromMillis(500);
expectException(
() -> Os.setsockoptTimeval(null, SOL_SOCKET, SO_RCVTIMEO, tv),
ErrnoException.class, EBADF, "setsockoptTimeval(null, ...)");
}
+ @Test
public void test_socket_setSockoptTimeval_fileFd() throws Exception {
File testFile = createTempFile("test_socket_setSockoptTimeval_invalidFd", "");
try (FileInputStream fis = new FileInputStream(testFile)) {
@@ -1195,6 +1235,7 @@
}
}
+ @Test
public void test_socket_setSockoptTimeval_badFd() throws Exception {
StructTimeval tv = StructTimeval.fromMillis(500);
FileDescriptor invalidFd = Os.socket(AF_INET6, SOCK_STREAM, 0);
@@ -1205,6 +1246,7 @@
ErrnoException.class, EBADF, "setsockoptTimeval(<closed fd>, ...)");
}
+ @Test
public void test_socket_setSockoptTimeval_invalidLevel() throws Exception {
StructTimeval tv = StructTimeval.fromMillis(500);
FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
@@ -1218,6 +1260,7 @@
}
}
+ @Test
public void test_socket_setSockoptTimeval_invalidOpt() throws Exception {
StructTimeval tv = StructTimeval.fromMillis(500);
FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
@@ -1231,6 +1274,7 @@
}
}
+ @Test
public void test_socket_setSockoptTimeval_nullTimeVal() throws Exception {
FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
try {
@@ -1242,6 +1286,7 @@
}
}
+ @Test
public void test_socket_getSockoptTimeval_invalidOption() throws Exception {
FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
try {
@@ -1254,19 +1299,22 @@
}
}
+ @Test
public void test_if_nametoindex_if_indextoname() throws Exception {
- List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
+ Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+ assertNotNull(networkInterfaces);
+ List<NetworkInterface> nis = Collections.list(networkInterfaces);
assertTrue(nis.size() > 0);
for (NetworkInterface ni : nis) {
int index = ni.getIndex();
String name = ni.getName();
assertEquals(index, Os.if_nametoindex(name));
- assertTrue(Os.if_indextoname(index).equals(name));
+ assertEquals(Os.if_indextoname(index), name);
}
assertEquals(0, Os.if_nametoindex("this-interface-does-not-exist"));
- assertEquals(null, Os.if_indextoname(-1000));
+ assertNull(Os.if_indextoname(-1000));
try {
Os.if_nametoindex(null);
@@ -1284,6 +1332,7 @@
}
}
+ @Test
public void test_readlink() throws Exception {
File path = new File(TestIoUtils.createTemporaryDirectory("test_readlink"), "symlink");
@@ -1294,17 +1343,18 @@
// failure are still on 3.18, far from current). Given that we don't
// really care here, just use 2048 instead. http://b/33306057.
int size = 2048;
- String xs = "";
+ StringBuilder xs = new StringBuilder();
for (int i = 0; i < size - 1; ++i) {
- xs += "x";
+ xs.append("x");
}
- Os.symlink(xs, path.getPath());
+ Os.symlink(xs.toString(), path.getPath());
- assertEquals(xs, Os.readlink(path.getPath()));
+ assertEquals(xs.toString(), Os.readlink(path.getPath()));
}
// Address should be correctly set for empty packets. http://b/33481605
+ @Test
public void test_recvfrom_EmptyPacket() throws Exception {
try (DatagramSocket ds = new DatagramSocket();
DatagramSocket srcSock = new DatagramSocket()) {
@@ -1320,6 +1370,7 @@
}
}
+ @Test
public void test_fstat_times() throws Exception {
File file = File.createTempFile("OsTest", "fstattest");
FileOutputStream fos = new FileOutputStream(file);
@@ -1338,6 +1389,7 @@
assertEquals(0, structStat1.st_atim.compareTo(structStat2.st_atim));
}
+ @Test
public void test_getrlimit() throws Exception {
StructRlimit rlimit = Os.getrlimit(OsConstants.RLIMIT_NOFILE);
// We can't really make any assertions about these values since they might vary from
@@ -1348,7 +1400,8 @@
}
// http://b/65051835
- public void test_pipe2_errno() throws Exception {
+ @Test
+ public void test_pipe2_errno() {
try {
// flag=-1 is not a valid value for pip2, will EINVAL
Os.pipe2(-1);
@@ -1358,7 +1411,8 @@
}
// http://b/65051835
- public void test_sendfile_errno() throws Exception {
+ @Test
+ public void test_sendfile_errno() {
try {
// FileDescriptor.out is not open for input, will cause EBADF
Int64Ref offset = new Int64Ref(10);
@@ -1368,6 +1422,7 @@
}
}
+ @Test
public void test_sendfile_null() throws Exception {
File in = createTempFile("test_sendfile_null", "Hello, world!");
try {
@@ -1378,6 +1433,7 @@
}
}
+ @Test
public void test_sendfile_offset() throws Exception {
File in = createTempFile("test_sendfile_offset", "Hello, world!");
try {
@@ -1417,6 +1473,7 @@
return f;
}
+ @Test
public void test_odirect() throws Exception {
File testFile = createTempFile("test_odirect", "");
try {
@@ -1433,6 +1490,7 @@
}
}
+ @Test
public void test_splice() throws Exception {
FileDescriptor[] pipe = Os.pipe2(0);
File in = createTempFile("splice1", "foobar");
@@ -1465,6 +1523,7 @@
Os.close(pipe[1]);
}
+ @Test
public void test_splice_errors() throws Exception {
File in = createTempFile("splice3", "");
File out = createTempFile("splice4", "");
@@ -1505,6 +1564,7 @@
Os.close(pipe[1]);
}
+ @Test
public void testCloseNullFileDescriptor() throws Exception {
try {
Os.close(null);
@@ -1513,6 +1573,7 @@
}
}
+ @Test
public void testSocketpairNullFileDescriptor1() throws Exception {
try {
Os.socketpair(AF_UNIX, SOCK_STREAM, 0, null, new FileDescriptor());
@@ -1521,6 +1582,7 @@
}
}
+ @Test
public void testSocketpairNullFileDescriptor2() throws Exception {
try {
Os.socketpair(AF_UNIX, SOCK_STREAM, 0, new FileDescriptor(), null);
@@ -1529,6 +1591,7 @@
}
}
+ @Test
public void testSocketpairNullFileDescriptorBoth() throws Exception {
try {
Os.socketpair(AF_UNIX, SOCK_STREAM, 0, null, null);
@@ -1537,30 +1600,35 @@
}
}
+ @Test
public void testInetPtonIpv4() {
String srcAddress = "127.0.0.1";
InetAddress inetAddress = Os.inet_pton(AF_INET, srcAddress);
assertEquals(srcAddress, inetAddress.getHostAddress());
}
+ @Test
public void testInetPtonIpv6() {
String srcAddress = "1123:4567:89ab:cdef:fedc:ba98:7654:3210";
InetAddress inetAddress = Os.inet_pton(AF_INET6, srcAddress);
assertEquals(srcAddress, inetAddress.getHostAddress());
}
+ @Test
public void testInetPtonInvalidFamily() {
String srcAddress = "127.0.0.1";
InetAddress inetAddress = Os.inet_pton(AF_UNIX, srcAddress);
assertNull(inetAddress);
}
+ @Test
public void testInetPtonWrongFamily() {
String srcAddress = "127.0.0.1";
InetAddress inetAddress = Os.inet_pton(AF_INET6, srcAddress);
assertNull(inetAddress);
}
+ @Test
public void testInetPtonInvalidData() {
String srcAddress = "10.1";
InetAddress inetAddress = Os.inet_pton(AF_INET, srcAddress);
@@ -1570,6 +1638,7 @@
/**
* Verifies the {@link OsConstants#MAP_ANONYMOUS}.
*/
+ @Test
public void testMapAnonymous() throws Exception {
final long size = 4096;
final long address = Os.mmap(0, size, PROT_READ,
@@ -1578,6 +1647,7 @@
Os.munmap(address, size);
}
+ @Test
public void testMemfdCreate() throws Exception {
FileDescriptor fd = null;
try {
@@ -1606,6 +1676,7 @@
}
}
+ @Test
public void testMemfdCreateFlags() throws Exception {
FileDescriptor fd = null;
@@ -1615,8 +1686,8 @@
assertNotNull(fd);
assertTrue(fd.valid());
int flags = Os.fcntlVoid(fd, F_GETFD);
- assertTrue("Expected flags to not include " + FD_CLOEXEC + ", actual value: " + flags,
- 0 == (flags & FD_CLOEXEC));
+ assertEquals("Expected flags to not include " + FD_CLOEXEC + ", actual value: " + flags,
+ 0, (flags & FD_CLOEXEC));
} finally {
if (fd != null) {
Os.close(fd);
@@ -1638,7 +1709,8 @@
}
}
- public void testMemfdCreateErrno() throws Exception {
+ @Test
+ public void testMemfdCreateErrno() {
expectException(() -> Os.memfd_create(null, 0), NullPointerException.class, null,
"memfd_create(null, 0)");
diff --git a/luni/src/test/java/libcore/highmemorytest/java/text/DateFormatTest.java b/luni/src/test/java/libcore/highmemorytest/java/text/DateFormatTest.java
new file mode 100644
index 0000000..257a5de
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/text/DateFormatTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.java.text;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Tests {@link DateFormat} but runs in a separate java package because loading data in all locales
+ * creates a lot of garbage / permanent heap growth in ICU4J and causes gcstress test failing
+ * in ART test environment. See http://b/161420453. No known users/apps load all locale data like
+ * this test.
+ */
+@RunWith(Parameterized.class)
+public class DateFormatTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter(0)
+ public Locale locale;
+
+ // 1 January 2022 00:00:00 GMT+00:00
+ private static final Date TEST_DATE = new Date(1640995200000L);
+
+ /**
+ * Test {@link DateFormat#format(Date)} does not crash on available locales.
+ */
+ @Test
+ public void test_format_allLocales() {
+ for (int formatStyle = DateFormat.FULL; formatStyle <= DateFormat.SHORT;
+ formatStyle++) {
+ try {
+ DateFormat.getDateInstance(formatStyle, locale)
+ .format(TEST_DATE);
+ DateFormat.getTimeInstance(formatStyle, locale)
+ .format(TEST_DATE);
+ DateFormat.getDateTimeInstance(formatStyle, formatStyle, locale)
+ .format(TEST_DATE);
+ } catch (RuntimeException cause) {
+ throw new RuntimeException("locale:" + locale +
+ " formatStyle:" + formatStyle, cause);
+ }
+ }
+ }
+
+ /**
+ * Test {@link SimpleDateFormat#toPattern()} contains only supported symbols.
+ */
+ @Test
+ public void test_toPattern_allLocales() {
+ for (int formatStyle = DateFormat.FULL; formatStyle <= DateFormat.SHORT;
+ formatStyle++) {
+ try {
+ assertSupportedSymbols(DateFormat.getDateInstance(formatStyle, locale), locale);
+ assertSupportedSymbols(DateFormat.getTimeInstance(formatStyle, locale), locale);
+ assertSupportedSymbols(DateFormat.getDateTimeInstance(
+ formatStyle, formatStyle, locale), locale);
+ } catch (RuntimeException cause) {
+ throw new RuntimeException("locale:" + locale +
+ " formatStyle:" + formatStyle, cause);
+ }
+ }
+ }
+
+ private static final Set<Character> SUPPORTED_SYMBOLS = "GyYMLwWDdFEuaHkKhmsSzZXLc".chars()
+ .mapToObj(c -> (char)c)
+ .collect(Collectors.toSet());
+
+ private static void assertSupportedSymbols(DateFormat dateFormat, Locale locale) {
+ SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormat;
+ String pattern = simpleDateFormat.toPattern();
+ // The string in the quotation is not interpreted.
+ boolean inQuotation = false;
+ for (int i = 0; i < pattern.length(); i++) {
+ char curr = pattern.charAt(i);
+ if (curr == '\'') {
+ inQuotation = !inQuotation;
+ continue;
+ }
+ if (inQuotation) {
+ continue;
+ }
+
+ if ((curr >= 'a' && curr <= 'z') || (curr >= 'A' && curr <= 'Z')) { // ASCII alphabets
+ assertTrue("Locale:" + locale + " Pattern:" + pattern + " has unsupported symbol "
+ + curr, SUPPORTED_SYMBOLS.contains(curr));
+ }
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/highmemorytest/java/text/DecimalFormatTest.java
new file mode 100644
index 0000000..9baf972
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/text/DecimalFormatTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.java.text;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Currency;
+import java.util.Locale;
+
+/**
+ * Runs in a separate java package because loading data in all locales creates a lot of garbage /
+ * permanent heap growth in ICU4J and causes gcstress test failing in ART test environment.
+ * See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class DecimalFormatTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter(0)
+ public Locale locale;
+
+ /**
+ * Test no extra spacing between currency symbol and the numeric amount
+ */
+ @Test
+ public void testCurrencySymbolSpacing() {
+ Currency currency = Currency.getInstance(Locale.US);
+ for (Locale locale : Locale.getAvailableLocales()) {
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale);
+ String formattedZero = new DecimalFormat("0", dfs).format(0);
+
+ assertCurrencyFormat("USD" + formattedZero, "\u00a4\u00a40", dfs, currency, locale);
+ assertCurrencyFormat(formattedZero + "USD", "0\u00a4\u00a4", dfs, currency, locale);
+ assertCurrencyFormat(currency.getSymbol(locale) + formattedZero, "\u00a40", dfs,
+ currency, locale);
+ assertCurrencyFormat(formattedZero + currency.getSymbol(locale), "0\u00a4", dfs,
+ currency, locale);
+ }
+ }
+
+ private static void assertCurrencyFormat(String expected, String pattern,
+ DecimalFormatSymbols dfs, Currency currency, Locale locale) {
+ DecimalFormat df = new DecimalFormat(pattern, dfs);
+ df.setCurrency(currency);
+ df.setMaximumFractionDigits(0);
+ assertEquals("Not formatted as expected with pattern " + pattern + " in locale " + locale,
+ expected, df.format(0));
+ }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/highmemorytest/java/text/SimpleDateFormatTest.java
new file mode 100644
index 0000000..63ec023
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/text/SimpleDateFormatTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.java.text;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Tests {@link SimpleDateFormat} but runs in a separate java package because loading data in all
+ * locales creates a lot of garbage / permanent heap growth in ICU4J and causes gcstress test
+ * failing in ART test environment. See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class SimpleDateFormatTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter(0)
+ public Locale locale;
+
+ @Test
+ public void testLocales() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzz", locale);
+ sdf.format(new Date(0));
+ }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/time/format/DateTimeFormatterTest.java b/luni/src/test/java/libcore/highmemorytest/java/time/format/DateTimeFormatterTest.java
new file mode 100644
index 0000000..e2d28ec
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/time/format/DateTimeFormatterTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.java.time.format;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.chrono.Chronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.time.temporal.TemporalAccessor;
+import java.util.Locale;
+
+/**
+ * Additional tests for {@link DateTimeFormatter}. Runs in a separate java package because
+ * loading data in all locales creates a lot of garbage / permanent heap growth in ICU4J and
+ * causes gcstress test failing in ART test environment. See http://b/161420453.
+ *
+ * @see tck.java.time.format.TCKDateTimeFormatter
+ * @see test.java.time.format.TestDateTimeFormatter
+ * @see libcore.java.time.format.DateTimeFormatterTest
+ */
+@RunWith(Parameterized.class)
+public class DateTimeFormatterTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter
+ public Locale locale;
+
+ // 1 January 2022 00:00:00 GMT+00:00
+ private static final Instant TEST_INSTANT = Instant.ofEpochSecond(1640995200L);
+
+ /**
+ * Test {@link DateTimeFormatter#format(TemporalAccessor)} does not crash on available locales.
+ */
+ @Test
+ public void test_format_allLocales() {
+ for (FormatStyle formatStyle : FormatStyle.values()) {
+ try {
+ DateTimeFormatter.ofLocalizedTime(formatStyle)
+ .withLocale(locale)
+ .withZone(ZoneOffset.UTC)
+ .format(TEST_INSTANT);
+
+ DateTimeFormatter.ofLocalizedDate(formatStyle)
+ .withLocale(locale)
+ .withZone(ZoneOffset.UTC)
+ .format(TEST_INSTANT);
+
+ DateTimeFormatter.ofLocalizedDateTime(formatStyle)
+ .withLocale(locale)
+ .withZone(ZoneOffset.UTC)
+ .format(TEST_INSTANT);
+ } catch (RuntimeException cause) {
+ throw new RuntimeException("formatStyle:" + formatStyle.name(), cause);
+ }
+ }
+ }
+
+ /**
+ * Test {@link DateTimeFormatter#format(TemporalAccessor)} does not crash on available locales
+ * with all possible Chronologies.
+ */
+ @Test
+ public void test_format_allLocales_allChronologies() {
+ for (Chronology chronology : Chronology.getAvailableChronologies()) {
+ for (FormatStyle formatStyle : FormatStyle.values()) {
+ try {
+ DateTimeFormatter.ofLocalizedTime(formatStyle)
+ .withLocale(locale)
+ .withChronology(chronology)
+ .withZone(ZoneOffset.UTC)
+ .format(TEST_INSTANT);
+
+ DateTimeFormatter.ofLocalizedDate(formatStyle)
+ .withLocale(locale)
+ .withChronology(chronology)
+ .withZone(ZoneOffset.UTC)
+ .format(TEST_INSTANT);
+
+ DateTimeFormatter.ofLocalizedDateTime(formatStyle)
+ .withLocale(locale)
+ .withChronology(chronology)
+ .withZone(ZoneOffset.UTC)
+ .format(TEST_INSTANT);
+ } catch (RuntimeException cause) {
+ throw new RuntimeException("Chronology:" + chronology +
+ " formatStyle:" + formatStyle.name(), cause);
+ }
+ }
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/util/CalendarTest.java b/luni/src/test/java/libcore/highmemorytest/java/util/CalendarTest.java
new file mode 100644
index 0000000..036ed9f
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/util/CalendarTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.java.util;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+/**
+ * Runs in a separate java package because loading data in all locales creates a lot of garbage /
+ * permanent heap growth in ICU4J and causes gcstress test failing in ART test environment.
+ * See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class CalendarTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter(0)
+ public Locale locale;
+
+ /**
+ * Ensures that Gregorian is the default Calendar for all Locales in Android. This is the
+ * historic behavior on Android; this test exists to avoid unintentional regressions.
+ * http://b/80294184
+ */
+ @Test
+ public void testAllDefaultCalendar_Gregorian() {
+ assertTrue("Default calendar should be Gregorian: " + locale,
+ Calendar.getInstance(locale) instanceof GregorianCalendar);
+ }
+
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/util/CurrencyTest.java b/luni/src/test/java/libcore/highmemorytest/java/util/CurrencyTest.java
new file mode 100644
index 0000000..d1cbf5e
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/util/CurrencyTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.java.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Currency;
+import java.util.Locale;
+
+/**
+ * Runs in a separate java package because loading data in all locales creates a lot of garbage /
+ * permanent heap growth in ICU4J and causes gcstress test failing in ART test environment.
+ * See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class CurrencyTest {
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter(0)
+ public Locale locale;
+
+ @Test
+ public void test_currencyCodeIcuConsistency() {
+ Currency javaCurrency = getCurrency(locale);
+ if (javaCurrency == null) {
+ return;
+ }
+ assertEquals("Currency code is not consistent:" + locale,
+ android.icu.util.Currency.getInstance(locale).getCurrencyCode(),
+ javaCurrency.getCurrencyCode());
+ }
+
+ private static Currency getCurrency(Locale l) {
+ try {
+ return Currency.getInstance(l);
+ } catch (IllegalArgumentException e) {
+ // The locale could have no country or does not have currency for other reasons.
+ return null;
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/libcore/icu/LocaleDataTest.java b/luni/src/test/java/libcore/highmemorytest/libcore/icu/LocaleDataTest.java
new file mode 100644
index 0000000..ab396f9
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/libcore/icu/LocaleDataTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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 libcore.highmemorytest.libcore.icu;
+
+import static org.junit.Assert.assertTrue;
+
+import libcore.icu.LocaleData;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Locale;
+
+@RunWith(Parameterized.class)
+public class LocaleDataTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Locale[] getAllLocales() {
+ return Locale.getAvailableLocales();
+ }
+
+ @Parameterized.Parameter(0)
+ public Locale locale;
+
+ @Test
+ public void testLongDateTimeFormat() {
+ LocaleData d = LocaleData.get(locale);
+ int dateLength = d.longDateFormat.length();
+ assertTrue("LocaleData.longDateFormat has zero length: " + dateLength, dateLength != 0);
+ int timeLength = d.longTimeFormat.length();
+ assertTrue("LocaleData.longTimeFormat has zero length: " + timeLength, timeLength != 0);
+ }
+}
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index 2b420bb..4e5e994 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -408,34 +408,6 @@
assertEquals(expected, numberFormat.format(2.01));
}
- /**
- * Test no extra spacing between currency symbol and the numeric amount
- */
- public void testCurrencySymbolSpacing() {
- Currency currency = Currency.getInstance(Locale.US);
- for (Locale locale : Locale.getAvailableLocales()) {
- DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale);
- String formattedZero = new DecimalFormat("0", dfs).format(0);
-
- assertCurrencyFormat("USD" + formattedZero, "\u00a4\u00a40", dfs, currency, locale);
- assertCurrencyFormat(formattedZero + "USD", "0\u00a4\u00a4", dfs, currency, locale);
- assertCurrencyFormat(currency.getSymbol(locale) + formattedZero, "\u00a40", dfs,
- currency, locale);
- assertCurrencyFormat(formattedZero + currency.getSymbol(locale), "0\u00a4", dfs,
- currency, locale);
- }
- }
-
- private static void assertCurrencyFormat(String expected, String pattern,
- DecimalFormatSymbols dfs,
- Currency currency, Locale locale) {
- DecimalFormat df = new DecimalFormat(pattern, dfs);
- df.setCurrency(currency);
- df.setMaximumFractionDigits(0);
- assertEquals("Not formatted as expected with pattern " + pattern + " in locale " + locale,
- expected, df.format(0));
- }
-
// http://b/27855939
public void testBug27855939() {
DecimalFormat df = new DecimalFormat("00");
diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
index 55a84e0..a1c206d 100644
--- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
@@ -388,15 +388,6 @@
assertEquals(20, calendar.get(Calendar.HOUR_OF_DAY)); // 9:00 GMT+11:00
assertEquals(0, calendar.get(Calendar.MINUTE));
}
-
- public void testLocales() throws Exception {
- // Just run through them all. Handy as a poor man's benchmark, and a confidence check.
- for (Locale l : Locale.getAvailableLocales()) {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzz", l);
- sdf.format(new Date(0));
- }
- }
-
// http://code.google.com/p/android/issues/detail?id=14963
public void testParseTimezoneOnly() throws Exception {
new SimpleDateFormat("z", Locale.FRANCE).parse("UTC");
diff --git a/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java b/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java
index 7ab33f7..7db90cd 100644
--- a/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java
+++ b/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java
@@ -106,71 +106,4 @@
assertEquals(23, accessor.getLong(ChronoField.HOUR_OF_DAY));
assertEquals(59, accessor.getLong(ChronoField.MINUTE_OF_HOUR));
}
-
-
- /**
- * Test {@link DateTimeFormatter#format(TemporalAccessor)} does not crash on available locales.
- */
- @Test
- public void test_format_allLocales() {
- for (Locale locale : Locale.getAvailableLocales()) {
- for (FormatStyle formatStyle : FormatStyle.values()) {
- try {
- DateTimeFormatter.ofLocalizedTime(formatStyle)
- .withLocale(locale)
- .withZone(ZoneOffset.UTC)
- .format(TEST_INSTANT);
-
- DateTimeFormatter.ofLocalizedDate(formatStyle)
- .withLocale(locale)
- .withZone(ZoneOffset.UTC)
- .format(TEST_INSTANT);
-
- DateTimeFormatter.ofLocalizedDateTime(formatStyle)
- .withLocale(locale)
- .withZone(ZoneOffset.UTC)
- .format(TEST_INSTANT);
- } catch (RuntimeException cause) {
- throw new RuntimeException("locale:" + locale +
- " formatStyle:" + formatStyle.name(), cause);
- }
- }
- }
- }
-
- /**
- * Test {@link DateTimeFormatter#format(TemporalAccessor)} does not crash on available locales
- * with all possible Chronologies.
- */
- @Test
- public void test_format_allLocales_allChronologies() {
- for (Locale locale : Locale.getAvailableLocales()) {
- for (Chronology chronology : Chronology.getAvailableChronologies()) {
- for (FormatStyle formatStyle : FormatStyle.values()) {
- try {
- DateTimeFormatter.ofLocalizedTime(formatStyle)
- .withLocale(locale)
- .withChronology(chronology)
- .withZone(ZoneOffset.UTC)
- .format(TEST_INSTANT);
-
- DateTimeFormatter.ofLocalizedDate(formatStyle)
- .withLocale(locale)
- .withChronology(chronology)
- .withZone(ZoneOffset.UTC)
- .format(TEST_INSTANT);
-
- DateTimeFormatter.ofLocalizedDateTime(formatStyle)
- .withLocale(locale)
- .withChronology(chronology)
- .withZone(ZoneOffset.UTC)
- .format(TEST_INSTANT);
- } catch (RuntimeException cause) {
- throw new RuntimeException("locale:" + locale +
- " formatStyle:" + formatStyle.name(), cause);
- }
- }
- }
- }
- }
}
diff --git a/luni/src/test/java/libcore/java/util/CalendarTest.java b/luni/src/test/java/libcore/java/util/CalendarTest.java
index cdeab95..abe5ab8 100644
--- a/luni/src/test/java/libcore/java/util/CalendarTest.java
+++ b/luni/src/test/java/libcore/java/util/CalendarTest.java
@@ -418,16 +418,4 @@
}
}
-
- /**
- * Ensures that Gregorian is the default Calendar for all Locales in Android. This is the
- * historic behavior on Android; this test exists to avoid unintentional regressions.
- * http://b/80294184
- */
- public void testAllDefaultCalendar_Gregorian() {
- for (Locale locale : Locale.getAvailableLocales()) {
- assertTrue("Default calendar should be Gregorian: " + locale,
- Calendar.getInstance(locale) instanceof GregorianCalendar);
- }
- }
}
diff --git a/luni/src/test/java/libcore/java/util/CurrencyTest.java b/luni/src/test/java/libcore/java/util/CurrencyTest.java
index 9acdde7..87f4315 100644
--- a/luni/src/test/java/libcore/java/util/CurrencyTest.java
+++ b/luni/src/test/java/libcore/java/util/CurrencyTest.java
@@ -195,17 +195,6 @@
}
}
- public void test_currencyCodeIcuConsistency() {
- Locale[] locales = Locale.getAvailableLocales();
- for (Locale l : locales) {
- Currency javaCurrency = getCurrency(l);
- if (javaCurrency == null) continue;
- assertEquals("Currency code is not consistent:" + l,
- android.icu.util.Currency.getInstance(l).getCurrencyCode(),
- javaCurrency.getCurrencyCode());
- }
- }
-
public void test_localeExtension() {
// Language=en, Country=US, Currency=Euro
Locale locale = Locale.forLanguageTag("en-US-u-cu-eur");
diff --git a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
index 637ccff..b524483 100644
--- a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
@@ -48,15 +48,6 @@
public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
@Test
- public void testAll() {
- // Test that we can get the locale data for all known locales.
- for (Locale l : Locale.getAvailableLocales()) {
- LocaleData d = LocaleData.get(l);
- System.err.format("%s %s %s\n", l, d.longDateFormat, d.longTimeFormat);
- }
- }
-
- @Test
public void test_en_US() throws Exception {
LocaleData l = LocaleData.get(Locale.US);
assertEquals("AM", l.amPm[0]);
diff --git a/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java b/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
index ef79442..31da1f1 100644
--- a/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
+++ b/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
@@ -20,11 +20,9 @@
import java.io.InputStream;
import java.io.ObjectInputStream;
-import java.nio.ByteBuffer;
import java.time.Instant;
import java.util.TimeZone;
-import libcore.timezone.testing.ZoneInfoTestHelper;
import libcore.util.ZoneInfo;
/**
@@ -51,19 +49,12 @@
zoneInfoRead = (ZoneInfo) object;
}
- long[][] transitions = {
- { -5000, 0 },
- { -2000, 1 },
- { -500, 0 },
- { 0, 2 },
- };
- int[][] types = {
- { 3600, 0 },
- { 1800, 1 },
- { 5400, 0 }
- };
- ZoneInfo zoneInfoCreated = createZoneInfo(
- "test", transitions, types, timeFromSeconds(-1));
+ long[] transitions = { -5000, -2000, -500, 0 };
+ byte[] types = { 0, 1, 0, 2 }; // align each entry with transitions
+ int[] offsets = { 3600, 1800, 5400 };
+ boolean[] isDsts = { false, true, false }; // align each entry with offsets
+ ZoneInfo zoneInfoCreated = createZoneInfo("TimeZone for 'test'", transitions, types, offsets,
+ isDsts, timeFromSeconds(-1));
assertEquals("Read ZoneInfo does not match created one", zoneInfoCreated, zoneInfoRead);
assertEquals("useDaylightTime() mismatch",
@@ -89,12 +80,9 @@
return Instant.ofEpochSecond(timeInSeconds);
}
- private ZoneInfo createZoneInfo(String name, long[][] transitions, int[][] types,
- Instant currentTime) throws Exception {
- ZoneInfoTestHelper.ZicDataBuilder builder =
- new ZoneInfoTestHelper.ZicDataBuilder()
- .setTransitionsAndTypes(transitions, types);
- ZoneInfoData data = ZoneInfoData.createZoneInfo(name, ByteBuffer.wrap(builder.build()));
+ private ZoneInfo createZoneInfo(String id, long[] transitions, byte[] types, int[] offsets,
+ boolean[] isDsts, Instant currentTime) {
+ ZoneInfoData data = ZoneInfoData.createInstance(id, transitions, types, offsets, isDsts);
return ZoneInfo.createZoneInfo(data, currentTime.toEpochMilli());
}
}
diff --git a/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java b/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
index c32e2d1..6b9fcc3 100644
--- a/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
+++ b/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
@@ -80,7 +80,7 @@
* final Runnable beeper = new Runnable() {
* public void run() { System.out.println("beep"); }
* };
- * final ScheduledFuture<?> beeperHandle =
+ * final ScheduledFuture<?< beeperHandle =
* scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
* scheduler.schedule(new Runnable() {
* public void run() { beeperHandle.cancel(true); }