1 /* 2 * Copyright (c) 2014, 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 24 /* 25 * @test 26 * @summary close handlers and closing streams 27 * @bug 8044047 28 */ 29 30 package org.openjdk.tests.java.util.stream; 31 32 import java.util.Arrays; 33 import java.util.stream.OpTestCase; 34 import java.util.stream.Stream; 35 36 import org.testng.annotations.Test; 37 38 import static java.util.stream.LambdaTestHelpers.countTo; 39 import static java.util.stream.ThowableHelper.checkNPE; 40 41 @Test(groups = { "serialization-hostile" }) 42 public class StreamCloseTest extends OpTestCase { 43 public void testNullCloseHandler() { 44 checkNPE(() -> Stream.of(1).onClose(null)); 45 } 46 47 public void testEmptyCloseHandler() { 48 try (Stream<Integer> ints = countTo(100).stream()) { 49 ints.forEach(i -> {}); 50 } 51 } 52 53 public void testOneCloseHandler() { 54 final boolean[] holder = new boolean[1]; 55 Runnable closer = () -> { holder[0] = true; }; 56 57 try (Stream<Integer> ints = countTo(100).stream()) { 58 ints.onClose(closer); 59 ints.forEach(i -> {}); 60 } 61 assertTrue(holder[0]); 62 63 Arrays.fill(holder, false); 64 try (Stream<Integer> ints = countTo(100).stream().onClose(closer)) { 65 ints.forEach(i -> {}); 66 } 67 assertTrue(holder[0]); 68 69 Arrays.fill(holder, false); 70 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer)) { 71 ints.forEach(i -> {}); 72 } 73 assertTrue(holder[0]); 74 75 Arrays.fill(holder, false); 76 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer).filter(e -> true)) { 77 ints.forEach(i -> {}); 78 } 79 assertTrue(holder[0]); 80 } 81 82 public void testTwoCloseHandlers() { 83 final boolean[] holder = new boolean[2]; 84 Runnable close1 = () -> { holder[0] = true; }; 85 Runnable close2 = () -> { holder[1] = true; }; 86 87 try (Stream<Integer> ints = countTo(100).stream()) { 88 ints.onClose(close1).onClose(close2); 89 ints.forEach(i -> {}); 90 } 91 assertTrue(holder[0] && holder[1]); 92 93 Arrays.fill(holder, false); 94 try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2)) { 95 ints.forEach(i -> {}); 96 } 97 assertTrue(holder[0] && holder[1]); 98 99 Arrays.fill(holder, false); 100 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2)) { 101 ints.forEach(i -> {}); 102 } 103 assertTrue(holder[0] && holder[1]); 104 105 Arrays.fill(holder, false); 106 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true)) { 107 ints.forEach(i -> {}); 108 } 109 assertTrue(holder[0] && holder[1]); 110 } 111 112 public void testCascadedExceptions() { 113 final boolean[] holder = new boolean[3]; 114 boolean caught = false; 115 Runnable close1 = () -> { holder[0] = true; throw new RuntimeException("1"); }; 116 Runnable close2 = () -> { holder[1] = true; throw new RuntimeException("2"); }; 117 Runnable close3 = () -> { holder[2] = true; throw new RuntimeException("3"); }; 118 119 try (Stream<Integer> ints = countTo(100).stream()) { 120 ints.onClose(close1).onClose(close2).onClose(close3); 121 ints.forEach(i -> {}); 122 } 123 catch (RuntimeException e) { 124 assertCascaded(e, 3); 125 assertTrue(holder[0] && holder[1] && holder[2]); 126 caught = true; 127 } 128 assertTrue(caught); 129 130 Arrays.fill(holder, false); 131 caught = false; 132 try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2).onClose(close3)) { 133 ints.forEach(i -> {}); 134 } 135 catch (RuntimeException e) { 136 assertCascaded(e, 3); 137 assertTrue(holder[0] && holder[1] && holder[2]); 138 caught = true; 139 } 140 assertTrue(caught); 141 142 caught = false; 143 Arrays.fill(holder, false); 144 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).onClose(close3)) { 145 ints.forEach(i -> {}); 146 } 147 catch (RuntimeException e) { 148 assertCascaded(e, 3); 149 assertTrue(holder[0] && holder[1] && holder[2]); 150 caught = true; 151 } 152 assertTrue(caught); 153 154 caught = false; 155 Arrays.fill(holder, false); 156 try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true).onClose(close3)) { 157 ints.forEach(i -> {}); 158 } 159 catch (RuntimeException e) { 160 assertCascaded(e, 3); 161 assertTrue(holder[0] && holder[1] && holder[2]); 162 caught = true; 163 } 164 assertTrue(caught); 165 } 166 167 private void assertCascaded(RuntimeException e, int n) { 168 assertTrue(e.getMessage().equals("1")); 169 assertTrue(e.getSuppressed().length == n - 1); 170 for (int i=0; i<n-1; i++) 171 assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2))); 172 } 173 }