--- old/test/TEST.ROOT 2017-06-12 20:31:31.541700987 -0700 +++ new/test/TEST.ROOT 2017-06-12 20:31:31.325808996 -0700 @@ -18,7 +18,7 @@ othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces javax/xml/jaxp/testng/validation java/lang/ProcessHandle # Tests that cannot run concurrently -exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi java/util/stream java/util/BitSet/stream javax/rmi com/sun/corba/cachedSocket +exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi java/util/stream java/util/Arrays/largeMemory java/util/BitSet/stream javax/rmi com/sun/corba/cachedSocket # Group definitions groups=TEST.groups [closed/TEST.groups] --- old/test/TEST.groups 2017-06-12 20:31:31.998472468 -0700 +++ new/test/TEST.groups 2017-06-12 20:31:31.837552975 -0700 @@ -1,4 +1,4 @@ -# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2017, 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 @@ -641,6 +641,7 @@ java/security/PermissionCollection/Concurrent.java \ java/security/Principal/Implies.java \ java/security/cert/GetInstance.java \ + java/util/Arrays/largeMemory/ParallelPrefix.java \ java/util/logging/DrainFindDeadlockTest.java \ java/util/logging/LoggingMXBeanTest.java \ java/util/logging/TestLogConfigurationDeadLock.java \ @@ -709,7 +710,6 @@ java/nio/Buffer/Chars.java \ java/nio/file/Files/StreamTest.java \ java/security/BasicPermission/Wildcard.java \ - java/util/Arrays/ParallelPrefix.java \ java/util/Arrays/SetAllTest.java \ java/util/BitSet/stream/BitSetStreamTest.java \ java/util/Collection/CollectionDefaults.java \ --- old/test/java/util/Arrays/ParallelPrefix.java 2017-06-12 20:31:32.623159942 -0700 +++ /dev/null 2017-06-12 02:41:33.853178592 -0700 @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2013, 2017, 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. - */ - -/** - * @test 8014076 8025067 - * @summary unit test for Arrays.ParallelPrefix(). - * @author Tristan Yan - * @run testng ParallelPrefix - */ - -import java.util.Arrays; -import java.util.function.BinaryOperator; -import java.util.function.DoubleBinaryOperator; -import java.util.function.Function; -import java.util.function.IntBinaryOperator; -import java.util.function.LongBinaryOperator; -import java.util.stream.IntStream; -import java.util.stream.LongStream; -import static org.testng.Assert.*; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -public class ParallelPrefix { - //Array size less than MIN_PARTITION - private static final int SMALL_ARRAY_SIZE = 1 << 3; - - //Array size equals MIN_PARTITION - private static final int THRESHOLD_ARRAY_SIZE = 1 << 4; - - //Array size greater than MIN_PARTITION - private static final int MEDIUM_ARRAY_SIZE = 1 << 8; - - //Array size much greater than MIN_PARTITION - private static final int LARGE_ARRAY_SIZE = 1 << 14; - - private static final int[] ARRAY_SIZE_COLLECTION = new int[]{ - SMALL_ARRAY_SIZE, - THRESHOLD_ARRAY_SIZE, - MEDIUM_ARRAY_SIZE, - LARGE_ARRAY_SIZE - }; - - @DataProvider(name = "intSet") - public static Object[][] intSet(){ - return genericData(size -> IntStream.range(0, size).toArray(), - new IntBinaryOperator[]{ - Integer::sum, - Integer::min}); - } - - @DataProvider(name = "longSet") - public static Object[][] longSet(){ - return genericData(size -> LongStream.range(0, size).toArray(), - new LongBinaryOperator[]{ - Long::sum, - Long::min}); - } - - @DataProvider(name = "doubleSet") - public static Object[][] doubleSet(){ - return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(), - new DoubleBinaryOperator[]{ - Double::sum, - Double::min}); - } - - @DataProvider(name = "stringSet") - public static Object[][] stringSet(){ - Function stringsFunc = size -> - IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new); - BinaryOperator concat = String::concat; - return genericData(stringsFunc, - (BinaryOperator[]) new BinaryOperator[]{ - concat }); - } - - private static Object[][] genericData(Function generateFunc, OPS[] ops) { - //test arrays which size is equals n-1, n, n+1, test random data - Object[][] data = new Object[ARRAY_SIZE_COLLECTION.length * 3 * ops.length][4]; - for(int n = 0; n < ARRAY_SIZE_COLLECTION.length; n++ ) { - for(int testValue = -1 ; testValue <= 1; testValue++) { - int array_size = ARRAY_SIZE_COLLECTION[n] + testValue; - for(int opsN = 0; opsN < ops.length; opsN++) { - int index = n * 3 * ops.length + (testValue + 1) * ops.length + opsN; - data[index][0] = generateFunc.apply(array_size); - data[index][1] = array_size / 3; - data[index][2] = 2 * array_size / 3; - data[index][3] = ops[opsN]; - } - } - } - return data; - } - - @Test(dataProvider="intSet") - public void testParallelPrefixForInt(int[] data, int fromIndex, int toIndex, IntBinaryOperator op) { - int[] sequentialResult = data.clone(); - for (int index = fromIndex + 1; index < toIndex; index++) { - sequentialResult[index ] = op.applyAsInt(sequentialResult[index - 1], sequentialResult[index]); - } - - int[] parallelResult = data.clone(); - Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); - assertArraysEqual(parallelResult, sequentialResult); - - int[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); - Arrays.parallelPrefix(parallelRangeResult, op); - assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); - } - - @Test(dataProvider="longSet") - public void testParallelPrefixForLong(long[] data, int fromIndex, int toIndex, LongBinaryOperator op) { - long[] sequentialResult = data.clone(); - for (int index = fromIndex + 1; index < toIndex; index++) { - sequentialResult[index ] = op.applyAsLong(sequentialResult[index - 1], sequentialResult[index]); - } - - long[] parallelResult = data.clone(); - Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); - assertArraysEqual(parallelResult, sequentialResult); - - long[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); - Arrays.parallelPrefix(parallelRangeResult, op); - assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); - } - - @Test(dataProvider="doubleSet") - public void testParallelPrefixForDouble(double[] data, int fromIndex, int toIndex, DoubleBinaryOperator op) { - double[] sequentialResult = data.clone(); - for (int index = fromIndex + 1; index < toIndex; index++) { - sequentialResult[index ] = op.applyAsDouble(sequentialResult[index - 1], sequentialResult[index]); - } - - double[] parallelResult = data.clone(); - Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); - assertArraysEqual(parallelResult, sequentialResult); - - double[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); - Arrays.parallelPrefix(parallelRangeResult, op); - assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); - } - - @Test(dataProvider="stringSet") - public void testParallelPrefixForStringr(String[] data , int fromIndex, int toIndex, BinaryOperator op) { - String[] sequentialResult = data.clone(); - for (int index = fromIndex + 1; index < toIndex; index++) { - sequentialResult[index ] = op.apply(sequentialResult[index - 1], sequentialResult[index]); - } - - String[] parallelResult = data.clone(); - Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); - assertArraysEqual(parallelResult, sequentialResult); - - String[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); - Arrays.parallelPrefix(parallelRangeResult, op); - assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); - } - - @Test - public void testNPEs() { - // null array - assertThrowsNPE(() -> Arrays.parallelPrefix((int[]) null, Integer::max)); - assertThrowsNPE(() -> Arrays.parallelPrefix((long []) null, Long::max)); - assertThrowsNPE(() -> Arrays.parallelPrefix((double []) null, Double::max)); - assertThrowsNPE(() -> Arrays.parallelPrefix((String []) null, String::concat)); - - // null array w/ range - assertThrowsNPE(() -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max)); - assertThrowsNPE(() -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max)); - assertThrowsNPE(() -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max)); - assertThrowsNPE(() -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat)); - - // null op - assertThrowsNPE(() -> Arrays.parallelPrefix(new int[] {}, null)); - assertThrowsNPE(() -> Arrays.parallelPrefix(new long[] {}, null)); - assertThrowsNPE(() -> Arrays.parallelPrefix(new double[] {}, null)); - assertThrowsNPE(() -> Arrays.parallelPrefix(new String[] {}, null)); - - // null op w/ range - assertThrowsNPE(() -> Arrays.parallelPrefix(new int[] {}, 0, 0, null)); - assertThrowsNPE(() -> Arrays.parallelPrefix(new long[] {}, 0, 0, null)); - assertThrowsNPE(() -> Arrays.parallelPrefix(new double[] {}, 0, 0, null)); - assertThrowsNPE(() -> Arrays.parallelPrefix(new String[] {}, 0, 0, null)); - } - - @Test - public void testIAEs() { - assertThrowsIAE(() -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max)); - assertThrowsIAE(() -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max)); - assertThrowsIAE(() -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max)); - assertThrowsIAE(() -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat)); - } - - @Test - public void testAIOOBEs() { - // bad "fromIndex" - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max)); - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max)); - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max)); - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat)); - - // bad "toIndex" - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max)); - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max)); - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max)); - assertThrowsAIOOB(() -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat)); - } - - // "library" code - - private void assertThrowsNPE(ThrowingRunnable r) { - assertThrows(NullPointerException.class, r); - } - - private void assertThrowsIAE(ThrowingRunnable r) { - assertThrows(IllegalArgumentException.class, r); - } - - private void assertThrowsAIOOB(ThrowingRunnable r) { - assertThrows(ArrayIndexOutOfBoundsException.class, r); - } - - static void assertArraysEqual(int[] actual, int[] expected) { - try { - assertEquals(actual, expected, ""); - } catch (AssertionError x) { - throw new AssertionError(String.format("Expected:%s, actual:%s", - Arrays.toString(expected), Arrays.toString(actual)), x); - } - } - - static void assertArraysEqual(long[] actual, long[] expected) { - try { - assertEquals(actual, expected, ""); - } catch (AssertionError x) { - throw new AssertionError(String.format("Expected:%s, actual:%s", - Arrays.toString(expected), Arrays.toString(actual)), x); - } - } - - static void assertArraysEqual(double[] actual, double[] expected) { - try { - assertEquals(actual, expected, ""); - } catch (AssertionError x) { - throw new AssertionError(String.format("Expected:%s, actual:%s", - Arrays.toString(expected), Arrays.toString(actual)), x); - } - } - - static void assertArraysEqual(String[] actual, String[] expected) { - try { - assertEquals(actual, expected, ""); - } catch (AssertionError x) { - throw new AssertionError(String.format("Expected:%s, actual:%s", - Arrays.toString(expected), Arrays.toString(actual)), x); - } - } -} - --- /dev/null 2017-06-12 02:41:33.853178592 -0700 +++ new/test/java/util/Arrays/largeMemory/ParallelPrefix.java 2017-06-12 20:31:32.400271451 -0700 @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2013, 2017, 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. + */ + +/** + * @test 8014076 8025067 + * @summary unit test for Arrays.ParallelPrefix(). + * @author Tristan Yan + * @modules java.management jdk.management + * @run testng/othervm -Xms256m -Xmx1024m ParallelPrefix + */ + +import java.lang.management.ManagementFactory; +import java.util.Arrays; +import java.util.function.BinaryOperator; +import java.util.function.DoubleBinaryOperator; +import java.util.function.Function; +import java.util.function.IntBinaryOperator; +import java.util.function.LongBinaryOperator; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import com.sun.management.OperatingSystemMXBean; +import static org.testng.Assert.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.testng.annotations.BeforeSuite; + +public class ParallelPrefix { + //Array size less than MIN_PARTITION + private static final int SMALL_ARRAY_SIZE = 1 << 3; + + //Array size equals MIN_PARTITION + private static final int THRESHOLD_ARRAY_SIZE = 1 << 4; + + //Array size greater than MIN_PARTITION + private static final int MEDIUM_ARRAY_SIZE = 1 << 8; + + //Array size much greater than MIN_PARTITION + private static final int LARGE_ARRAY_SIZE = 1 << 14; + + private static int[] arraySizeCollection; + + @BeforeSuite + public static void setup() { + java.lang.management.OperatingSystemMXBean bean = + ManagementFactory.getOperatingSystemMXBean(); + if (bean instanceof OperatingSystemMXBean) { + OperatingSystemMXBean os = (OperatingSystemMXBean)bean; + long physicalMemorySize = os.getTotalPhysicalMemorySize() / (1024 * 1024); + System.out.println("System memory size: " + physicalMemorySize + "M"); + // when we can get system memory size, and it's larger than 2G, + // then we enable large array size test below, + // else disable large array size test below. + if (physicalMemorySize > (2 * 1024)) { + arraySizeCollection = new int[]{ + SMALL_ARRAY_SIZE, + THRESHOLD_ARRAY_SIZE, + MEDIUM_ARRAY_SIZE, + LARGE_ARRAY_SIZE + }; + System.out.println("System memory is large enough, add large array size test"); + return; + } + } + arraySizeCollection = new int[]{ + SMALL_ARRAY_SIZE, + THRESHOLD_ARRAY_SIZE, + MEDIUM_ARRAY_SIZE + }; + System.out.println("System memory is not large enough, remove large array size test"); + } + + @DataProvider(name = "intSet") + public static Object[][] intSet(){ + return genericData(size -> IntStream.range(0, size).toArray(), + new IntBinaryOperator[]{ + Integer::sum, + Integer::min}); + } + + @DataProvider(name = "longSet") + public static Object[][] longSet(){ + return genericData(size -> LongStream.range(0, size).toArray(), + new LongBinaryOperator[]{ + Long::sum, + Long::min}); + } + + @DataProvider(name = "doubleSet") + public static Object[][] doubleSet(){ + return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(), + new DoubleBinaryOperator[]{ + Double::sum, + Double::min}); + } + + @DataProvider(name = "stringSet") + public static Object[][] stringSet(){ + Function stringsFunc = size -> + IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new); + BinaryOperator concat = String::concat; + return genericData(stringsFunc, + (BinaryOperator[]) new BinaryOperator[]{ + concat }); + } + + private static Object[][] genericData(Function generateFunc, OPS[] ops) { + //test arrays which size is equals n-1, n, n+1, test random data + Object[][] data = new Object[arraySizeCollection.length * 3 * ops.length][4]; + for(int n = 0; n < arraySizeCollection.length; n++ ) { + for(int testValue = -1 ; testValue <= 1; testValue++) { + int array_size = arraySizeCollection[n] + testValue; + for(int opsN = 0; opsN < ops.length; opsN++) { + int index = n * 3 * ops.length + (testValue + 1) * ops.length + opsN; + data[index][0] = generateFunc.apply(array_size); + data[index][1] = array_size / 3; + data[index][2] = 2 * array_size / 3; + data[index][3] = ops[opsN]; + } + } + } + return data; + } + + @Test(dataProvider="intSet") + public void testParallelPrefixForInt(int[] data, int fromIndex, int toIndex, IntBinaryOperator op) { + int[] sequentialResult = data.clone(); + for (int index = fromIndex + 1; index < toIndex; index++) { + sequentialResult[index ] = op.applyAsInt(sequentialResult[index - 1], sequentialResult[index]); + } + + int[] parallelResult = data.clone(); + Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); + assertArraysEqual(parallelResult, sequentialResult); + + int[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); + Arrays.parallelPrefix(parallelRangeResult, op); + assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); + } + + @Test(dataProvider="longSet") + public void testParallelPrefixForLong(long[] data, int fromIndex, int toIndex, LongBinaryOperator op) { + long[] sequentialResult = data.clone(); + for (int index = fromIndex + 1; index < toIndex; index++) { + sequentialResult[index ] = op.applyAsLong(sequentialResult[index - 1], sequentialResult[index]); + } + + long[] parallelResult = data.clone(); + Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); + assertArraysEqual(parallelResult, sequentialResult); + + long[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); + Arrays.parallelPrefix(parallelRangeResult, op); + assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); + } + + @Test(dataProvider="doubleSet") + public void testParallelPrefixForDouble(double[] data, int fromIndex, int toIndex, DoubleBinaryOperator op) { + double[] sequentialResult = data.clone(); + for (int index = fromIndex + 1; index < toIndex; index++) { + sequentialResult[index ] = op.applyAsDouble(sequentialResult[index - 1], sequentialResult[index]); + } + + double[] parallelResult = data.clone(); + Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); + assertArraysEqual(parallelResult, sequentialResult); + + double[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); + Arrays.parallelPrefix(parallelRangeResult, op); + assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); + } + + @Test(dataProvider="stringSet") + public void testParallelPrefixForStringr(String[] data , int fromIndex, int toIndex, BinaryOperator op) { + String[] sequentialResult = data.clone(); + for (int index = fromIndex + 1; index < toIndex; index++) { + sequentialResult[index ] = op.apply(sequentialResult[index - 1], sequentialResult[index]); + } + + String[] parallelResult = data.clone(); + Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op); + assertArraysEqual(parallelResult, sequentialResult); + + String[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex); + Arrays.parallelPrefix(parallelRangeResult, op); + assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); + } + + @Test + public void testNPEs() { + // null array + assertThrowsNPE(() -> Arrays.parallelPrefix((int[]) null, Integer::max)); + assertThrowsNPE(() -> Arrays.parallelPrefix((long []) null, Long::max)); + assertThrowsNPE(() -> Arrays.parallelPrefix((double []) null, Double::max)); + assertThrowsNPE(() -> Arrays.parallelPrefix((String []) null, String::concat)); + + // null array w/ range + assertThrowsNPE(() -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max)); + assertThrowsNPE(() -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max)); + assertThrowsNPE(() -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max)); + assertThrowsNPE(() -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat)); + + // null op + assertThrowsNPE(() -> Arrays.parallelPrefix(new int[] {}, null)); + assertThrowsNPE(() -> Arrays.parallelPrefix(new long[] {}, null)); + assertThrowsNPE(() -> Arrays.parallelPrefix(new double[] {}, null)); + assertThrowsNPE(() -> Arrays.parallelPrefix(new String[] {}, null)); + + // null op w/ range + assertThrowsNPE(() -> Arrays.parallelPrefix(new int[] {}, 0, 0, null)); + assertThrowsNPE(() -> Arrays.parallelPrefix(new long[] {}, 0, 0, null)); + assertThrowsNPE(() -> Arrays.parallelPrefix(new double[] {}, 0, 0, null)); + assertThrowsNPE(() -> Arrays.parallelPrefix(new String[] {}, 0, 0, null)); + } + + @Test + public void testIAEs() { + assertThrowsIAE(() -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max)); + assertThrowsIAE(() -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max)); + assertThrowsIAE(() -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max)); + assertThrowsIAE(() -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat)); + } + + @Test + public void testAIOOBEs() { + // bad "fromIndex" + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max)); + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max)); + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max)); + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat)); + + // bad "toIndex" + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max)); + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max)); + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max)); + assertThrowsAIOOB(() -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat)); + } + + // "library" code + + private void assertThrowsNPE(ThrowingRunnable r) { + assertThrows(NullPointerException.class, r); + } + + private void assertThrowsIAE(ThrowingRunnable r) { + assertThrows(IllegalArgumentException.class, r); + } + + private void assertThrowsAIOOB(ThrowingRunnable r) { + assertThrows(ArrayIndexOutOfBoundsException.class, r); + } + + static void assertArraysEqual(int[] actual, int[] expected) { + try { + assertEquals(actual, expected, ""); + } catch (AssertionError x) { + throw new AssertionError(String.format("Expected:%s, actual:%s", + Arrays.toString(expected), Arrays.toString(actual)), x); + } + } + + static void assertArraysEqual(long[] actual, long[] expected) { + try { + assertEquals(actual, expected, ""); + } catch (AssertionError x) { + throw new AssertionError(String.format("Expected:%s, actual:%s", + Arrays.toString(expected), Arrays.toString(actual)), x); + } + } + + static void assertArraysEqual(double[] actual, double[] expected) { + try { + assertEquals(actual, expected, ""); + } catch (AssertionError x) { + throw new AssertionError(String.format("Expected:%s, actual:%s", + Arrays.toString(expected), Arrays.toString(actual)), x); + } + } + + static void assertArraysEqual(String[] actual, String[] expected) { + try { + assertEquals(actual, expected, ""); + } catch (AssertionError x) { + throw new AssertionError(String.format("Expected:%s, actual:%s", + Arrays.toString(expected), Arrays.toString(actual)), x); + } + } +} +