1 /* 2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.tests.java.util.stream; 24 25 import org.openjdk.testlib.java.util.stream.OpTestCase; 26 27 import java.util.Arrays; 28 import java.util.stream.Stream; 29 30 import org.testng.annotations.Test; 31 32 import static org.openjdk.testlib.java.util.stream.LambdaTestHelpers.countTo; 33 34 35 import static org.openjdk.testlib.java.util.stream.LambdaTestHelpers.countTo; 36 import static org.openjdk.testlib.java.util.stream.ThrowableHelper.checkNPE; 37 import static org.openjdk.testlib.java.util.stream.ThrowableHelper.checkISE; 38 39 /* 40 * @test 41 * @summary close handlers and closing streams 42 * @bug 8044047 8147505 43 */ 44 @Test(groups = { "serialization-hostile" }) 45 public class StreamCloseTest extends OpTestCase { testNullCloseHandler()46 public void testNullCloseHandler() { 47 checkNPE(() -> Stream.of(1).onClose(null)); 48 } testEmptyCloseHandler()49 public void testEmptyCloseHandler() { 50 try (Stream<Integer> ints = countTo(100).stream()) { 51 ints.forEach(i -> {}); 52 } 53 } 54 testOneCloseHandler()55 public void testOneCloseHandler() { 56 final boolean[] holder = new boolean[1]; 57 Runnable closer = () -> { holder[0] = true; }; 58 59 try (Stream<Integer> ints = countTo(100).stream()) { 60 ints.onClose(closer); 61 ints.forEach(i -> {}); 62 } 63 assertTrue(holder[0]); 64 65 Arrays.fill(holder, false); 66 try (Stream<Integer> ints = countTo(100).stream().onClose(closer)) { 67 ints.forEach(i -> {}); 68 } 69 assertTrue(holder[0]); 70 71 Arrays.fill(holder, false); 72 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer)) { 73 ints.forEach(i -> {}); 74 } 75 assertTrue(holder[0]); 76 77 Arrays.fill(holder, false); 78 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer).filter(e -> true)) { 79 ints.forEach(i -> {}); 80 } 81 assertTrue(holder[0]); 82 } 83 testTwoCloseHandlers()84 public void testTwoCloseHandlers() { 85 final boolean[] holder = new boolean[2]; 86 Runnable close1 = () -> { holder[0] = true; }; 87 Runnable close2 = () -> { holder[1] = true; }; 88 89 try (Stream<Integer> ints = countTo(100).stream()) { 90 ints.onClose(close1).onClose(close2); 91 ints.forEach(i -> {}); 92 } 93 assertTrue(holder[0] && holder[1]); 94 95 Arrays.fill(holder, false); 96 try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2)) { 97 ints.forEach(i -> {}); 98 } 99 assertTrue(holder[0] && holder[1]); 100 101 Arrays.fill(holder, false); 102 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2)) { 103 ints.forEach(i -> {}); 104 } 105 assertTrue(holder[0] && holder[1]); 106 107 Arrays.fill(holder, false); 108 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true)) { 109 ints.forEach(i -> {}); 110 } 111 assertTrue(holder[0] && holder[1]); 112 } 113 testCascadedExceptions()114 public void testCascadedExceptions() { 115 final boolean[] holder = new boolean[3]; 116 boolean caught = false; 117 Runnable close1 = () -> { holder[0] = true; throw new RuntimeException("1"); }; 118 Runnable close2 = () -> { holder[1] = true; throw new RuntimeException("2"); }; 119 Runnable close3 = () -> { holder[2] = true; throw new RuntimeException("3"); }; 120 121 try (Stream<Integer> ints = countTo(100).stream()) { 122 ints.onClose(close1).onClose(close2).onClose(close3); 123 ints.forEach(i -> {}); 124 } 125 catch (RuntimeException e) { 126 assertCascaded(e, 3); 127 assertTrue(holder[0] && holder[1] && holder[2]); 128 caught = true; 129 } 130 assertTrue(caught); 131 132 Arrays.fill(holder, false); 133 caught = false; 134 try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2).onClose(close3)) { 135 ints.forEach(i -> {}); 136 } 137 catch (RuntimeException e) { 138 assertCascaded(e, 3); 139 assertTrue(holder[0] && holder[1] && holder[2]); 140 caught = true; 141 } 142 assertTrue(caught); 143 144 caught = false; 145 Arrays.fill(holder, false); 146 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).onClose(close3)) { 147 ints.forEach(i -> {}); 148 } 149 catch (RuntimeException e) { 150 assertCascaded(e, 3); 151 assertTrue(holder[0] && holder[1] && holder[2]); 152 caught = true; 153 } 154 assertTrue(caught); 155 156 caught = false; 157 Arrays.fill(holder, false); 158 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true).onClose(close3)) { 159 ints.forEach(i -> {}); 160 } 161 catch (RuntimeException e) { 162 assertCascaded(e, 3); 163 assertTrue(holder[0] && holder[1] && holder[2]); 164 caught = true; 165 } 166 assertTrue(caught); 167 } 168 assertCascaded(RuntimeException e, int n)169 private void assertCascaded(RuntimeException e, int n) { 170 assertTrue(e.getMessage().equals("1")); 171 assertTrue(e.getSuppressed().length == n - 1); 172 for (int i=0; i<n-1; i++) 173 assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2))); 174 } 175 testConsumed()176 public void testConsumed() { 177 try(Stream<Integer> s = countTo(100).stream()) { 178 s.forEach(i -> {}); 179 // Adding onClose handler when stream is consumed is illegal 180 // handler must not be registered 181 checkISE(() -> s.onClose(() -> fail("1"))); 182 } 183 184 // close() must be idempotent: 185 // second close() invoked at the end of try-with-resources must have no effect 186 try(Stream<Integer> s = countTo(100).stream()) { 187 s.close(); 188 // Adding onClose handler when stream is closed is also illegal 189 checkISE(() -> s.onClose(() -> fail("3"))); 190 } 191 } 192 } 193