1 /*
2  * Copyright (c) 2013, 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  * StreamCloseTest
36  *
37  * @author Brian Goetz
38  */
39 @Test(groups = { "serialization-hostile" })
40 public class StreamCloseTest extends OpTestCase {
testEmptyCloseHandler()41     public void testEmptyCloseHandler() {
42         try (Stream<Integer> ints = countTo(100).stream()) {
43             ints.forEach(i -> {});
44         }
45     }
46 
testOneCloseHandler()47     public void testOneCloseHandler() {
48         final boolean[] holder = new boolean[1];
49         Runnable closer = () -> { holder[0] = true; };
50 
51         try (Stream<Integer> ints = countTo(100).stream()) {
52             ints.onClose(closer);
53             ints.forEach(i -> {});
54         }
55         assertTrue(holder[0]);
56 
57         Arrays.fill(holder, false);
58         try (Stream<Integer> ints = countTo(100).stream().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().filter(e -> true).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).filter(e -> true)) {
71             ints.forEach(i -> {});
72         }
73         assertTrue(holder[0]);
74     }
75 
testTwoCloseHandlers()76     public void testTwoCloseHandlers() {
77         final boolean[] holder = new boolean[2];
78         Runnable close1 = () -> { holder[0] = true; };
79         Runnable close2 = () -> { holder[1] = true; };
80 
81         try (Stream<Integer> ints = countTo(100).stream()) {
82             ints.onClose(close1).onClose(close2);
83             ints.forEach(i -> {});
84         }
85         assertTrue(holder[0] && holder[1]);
86 
87         Arrays.fill(holder, false);
88         try (Stream<Integer> ints = countTo(100).stream().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().filter(e -> true).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).filter(e -> true)) {
101             ints.forEach(i -> {});
102         }
103         assertTrue(holder[0] && holder[1]);
104     }
105 
testCascadedExceptions()106     public void testCascadedExceptions() {
107         final boolean[] holder = new boolean[3];
108         boolean caught = false;
109         Runnable close1 = () -> { holder[0] = true; throw new RuntimeException("1"); };
110         Runnable close2 = () -> { holder[1] = true; throw new RuntimeException("2"); };
111         Runnable close3 = () -> { holder[2] = true; throw new RuntimeException("3"); };
112 
113         try (Stream<Integer> ints = countTo(100).stream()) {
114             ints.onClose(close1).onClose(close2).onClose(close3);
115             ints.forEach(i -> {});
116         }
117         catch (RuntimeException e) {
118             assertCascaded(e, 3);
119             assertTrue(holder[0] && holder[1] && holder[2]);
120             caught = true;
121         }
122         assertTrue(caught);
123 
124         Arrays.fill(holder, false);
125         caught = false;
126         try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2).onClose(close3)) {
127             ints.forEach(i -> {});
128         }
129         catch (RuntimeException e) {
130             assertCascaded(e, 3);
131             assertTrue(holder[0] && holder[1] && holder[2]);
132             caught = true;
133         }
134         assertTrue(caught);
135 
136         caught = false;
137         Arrays.fill(holder, false);
138         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).onClose(close3)) {
139             ints.forEach(i -> {});
140         }
141         catch (RuntimeException e) {
142             assertCascaded(e, 3);
143             assertTrue(holder[0] && holder[1] && holder[2]);
144             caught = true;
145         }
146         assertTrue(caught);
147 
148         caught = false;
149         Arrays.fill(holder, false);
150         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true).onClose(close3)) {
151             ints.forEach(i -> {});
152         }
153         catch (RuntimeException e) {
154             assertCascaded(e, 3);
155             assertTrue(holder[0] && holder[1] && holder[2]);
156             caught = true;
157         }
158         assertTrue(caught);
159     }
160 
assertCascaded(RuntimeException e, int n)161     private void assertCascaded(RuntimeException e, int n) {
162         assertTrue(e.getMessage().equals("1"));
163         assertTrue(e.getSuppressed().length == n - 1);
164         for (int i=0; i<n-1; i++)
165         assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2)));
166     }
167 }
168