1 /*
   2  * Copyright (c) 2012, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package org.openjdk.tests.java.util.stream;
  26 
  27 import java.util.Arrays;
  28 import java.util.stream.OpTestCase;
  29 import java.util.stream.Stream;
  30 
  31 import static java.util.stream.LambdaTestHelpers.countTo;
  32 
  33 /**
  34  * StreamCloseTest
  35  *
  36  * @author Brian Goetz
  37  */
  38 public class StreamCloseTest extends OpTestCase {
  39     public void testEmptyCloseHandler() {
  40         try (Stream<Integer> ints = countTo(100).stream()) {
  41             ints.forEach(i -> {});
  42         }
  43     }
  44 
  45     public void testOneCloseHandler() {
  46         final boolean[] holder = new boolean[1];
  47         Runnable closer = () -> { holder[0] = true; };
  48 
  49         try (Stream<Integer> ints = countTo(100).stream()) {
  50             ints.onClose(closer);
  51             ints.forEach(i -> {});
  52         }
  53         assertTrue(holder[0]);
  54 
  55         Arrays.fill(holder, false);
  56         try (Stream<Integer> ints = countTo(100).stream().onClose(closer)) {
  57             ints.forEach(i -> {});
  58         }
  59         assertTrue(holder[0]);
  60 
  61         Arrays.fill(holder, false);
  62         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer)) {
  63             ints.forEach(i -> {});
  64         }
  65         assertTrue(holder[0]);
  66 
  67         Arrays.fill(holder, false);
  68         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer).filter(e -> true)) {
  69             ints.forEach(i -> {});
  70         }
  71         assertTrue(holder[0]);
  72     }
  73 
  74     public void testTwoCloseHandlers() {
  75         final boolean[] holder = new boolean[2];
  76         Runnable close1 = () -> { holder[0] = true; };
  77         Runnable close2 = () -> { holder[1] = true; };
  78 
  79         try (Stream<Integer> ints = countTo(100).stream()) {
  80             ints.onClose(close1).onClose(close2);
  81             ints.forEach(i -> {});
  82         }
  83         assertTrue(holder[0] && holder[1]);
  84 
  85         Arrays.fill(holder, false);
  86         try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2)) {
  87             ints.forEach(i -> {});
  88         }
  89         assertTrue(holder[0] && holder[1]);
  90 
  91         Arrays.fill(holder, false);
  92         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2)) {
  93             ints.forEach(i -> {});
  94         }
  95         assertTrue(holder[0] && holder[1]);
  96 
  97         Arrays.fill(holder, false);
  98         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true)) {
  99             ints.forEach(i -> {});
 100         }
 101         assertTrue(holder[0] && holder[1]);
 102     }
 103 
 104     public void testCascadedExceptions() {
 105         final boolean[] holder = new boolean[3];
 106         boolean caught = false;
 107         Runnable close1 = () -> { holder[0] = true; throw new RuntimeException("1"); };
 108         Runnable close2 = () -> { holder[1] = true; throw new RuntimeException("2"); };
 109         Runnable close3 = () -> { holder[2] = true; throw new RuntimeException("3"); };
 110 
 111         try (Stream<Integer> ints = countTo(100).stream()) {
 112             ints.onClose(close1).onClose(close2).onClose(close3);
 113             ints.forEach(i -> {});
 114         }
 115         catch (RuntimeException e) {
 116             assertCascaded(e, 3);
 117             assertTrue(holder[0] && holder[1] && holder[2]);
 118             caught = true;
 119         }
 120         assertTrue(caught);
 121 
 122         Arrays.fill(holder, false);
 123         caught = false;
 124         try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2).onClose(close3)) {
 125             ints.forEach(i -> {});
 126         }
 127         catch (RuntimeException e) {
 128             assertCascaded(e, 3);
 129             assertTrue(holder[0] && holder[1] && holder[2]);
 130             caught = true;
 131         }
 132         assertTrue(caught);
 133 
 134         caught = false;
 135         Arrays.fill(holder, false);
 136         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).onClose(close3)) {
 137             ints.forEach(i -> {});
 138         }
 139         catch (RuntimeException e) {
 140             assertCascaded(e, 3);
 141             assertTrue(holder[0] && holder[1] && holder[2]);
 142             caught = true;
 143         }
 144         assertTrue(caught);
 145 
 146         caught = false;
 147         Arrays.fill(holder, false);
 148         try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true).onClose(close3)) {
 149             ints.forEach(i -> {});
 150         }
 151         catch (RuntimeException e) {
 152             assertCascaded(e, 3);
 153             assertTrue(holder[0] && holder[1] && holder[2]);
 154             caught = true;
 155         }
 156         assertTrue(caught);
 157     }
 158 
 159     private void assertCascaded(RuntimeException e, int n) {
 160         assertTrue(e.getMessage().equals("1"));
 161         assertTrue(e.getSuppressed().length == n - 1);
 162         for (int i=0; i<n-1; i++)
 163         assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2)));
 164     }
 165 }