1 /* 2 * Copyright (c) 2018, 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 package jdk.internal.net.http.common; 25 26 import org.testng.annotations.DataProvider; 27 import org.testng.annotations.Test; 28 29 import java.util.concurrent.CompletableFuture; 30 import java.util.concurrent.CompletionException; 31 import java.util.concurrent.ExecutorService; 32 import java.util.concurrent.Executors; 33 34 import static org.testng.Assert.assertThrows; 35 36 public class MinimalFutureTest { 37 38 @Test(dataProvider = "futures") test(CompletableFuture<Object> mf)39 public void test(CompletableFuture<Object> mf) { 40 ExecutorService executor = Executors.newSingleThreadExecutor(); 41 try { 42 assertNoObtrusion(mf.thenApply(MinimalFutureTest::apply)); 43 assertNoObtrusion(mf.thenApplyAsync(MinimalFutureTest::apply)); 44 assertNoObtrusion(mf.thenApplyAsync(MinimalFutureTest::apply, executor)); 45 46 assertNoObtrusion(mf.thenAccept(MinimalFutureTest::accept)); 47 assertNoObtrusion(mf.thenAcceptAsync(MinimalFutureTest::accept)); 48 assertNoObtrusion(mf.thenAcceptAsync(MinimalFutureTest::accept, executor)); 49 50 assertNoObtrusion(mf.thenRun(MinimalFutureTest::run)); 51 assertNoObtrusion(mf.thenRunAsync(MinimalFutureTest::run)); 52 assertNoObtrusion(mf.thenRunAsync(MinimalFutureTest::run, executor)); 53 54 assertNoObtrusion(mf.thenCombine(otherFuture(), MinimalFutureTest::apply)); 55 assertNoObtrusion(mf.thenCombineAsync(otherFuture(), MinimalFutureTest::apply)); 56 assertNoObtrusion(mf.thenCombineAsync(otherFuture(), MinimalFutureTest::apply, executor)); 57 58 assertNoObtrusion(mf.thenAcceptBoth(otherFuture(), MinimalFutureTest::accept)); 59 assertNoObtrusion(mf.thenAcceptBothAsync(otherFuture(), MinimalFutureTest::accept)); 60 assertNoObtrusion(mf.thenAcceptBothAsync(otherFuture(), MinimalFutureTest::accept, executor)); 61 62 assertNoObtrusion(mf.runAfterBoth(otherFuture(), MinimalFutureTest::run)); 63 assertNoObtrusion(mf.runAfterBothAsync(otherFuture(), MinimalFutureTest::run)); 64 assertNoObtrusion(mf.runAfterBothAsync(otherFuture(), MinimalFutureTest::run, executor)); 65 66 // "either" methods may return something else if otherFuture() is 67 // not MinimalFuture 68 69 assertNoObtrusion(mf.applyToEither(otherFuture(), MinimalFutureTest::apply)); 70 assertNoObtrusion(mf.applyToEitherAsync(otherFuture(), MinimalFutureTest::apply)); 71 assertNoObtrusion(mf.applyToEitherAsync(otherFuture(), MinimalFutureTest::apply, executor)); 72 73 assertNoObtrusion(mf.acceptEither(otherFuture(), MinimalFutureTest::accept)); 74 assertNoObtrusion(mf.acceptEitherAsync(otherFuture(), MinimalFutureTest::accept)); 75 assertNoObtrusion(mf.acceptEitherAsync(otherFuture(), MinimalFutureTest::accept, executor)); 76 77 assertNoObtrusion(mf.runAfterEither(otherFuture(), MinimalFutureTest::run)); 78 assertNoObtrusion(mf.runAfterEitherAsync(otherFuture(), MinimalFutureTest::run)); 79 assertNoObtrusion(mf.runAfterEitherAsync(otherFuture(), MinimalFutureTest::run, executor)); 80 81 assertNoObtrusion(mf.thenCompose(MinimalFutureTest::completionStageOf)); 82 assertNoObtrusion(mf.thenComposeAsync(MinimalFutureTest::completionStageOf)); 83 assertNoObtrusion(mf.thenComposeAsync(MinimalFutureTest::completionStageOf, executor)); 84 85 assertNoObtrusion(mf.handle(MinimalFutureTest::relay)); 86 assertNoObtrusion(mf.handleAsync(MinimalFutureTest::relay)); 87 assertNoObtrusion(mf.handleAsync(MinimalFutureTest::relay, executor)); 88 89 assertNoObtrusion(mf.whenComplete(MinimalFutureTest::accept)); 90 assertNoObtrusion(mf.whenCompleteAsync(MinimalFutureTest::accept)); 91 assertNoObtrusion(mf.whenCompleteAsync(MinimalFutureTest::accept, executor)); 92 93 assertNoObtrusion(mf.toCompletableFuture()); 94 assertNoObtrusion(mf.exceptionally(t -> null)); 95 96 assertNoObtrusion(mf); 97 assertNoObtrusion(mf.copy()); 98 assertNoObtrusion(mf.newIncompleteFuture()); 99 } finally { 100 executor.shutdownNow(); 101 } 102 } 103 otherFuture()104 private static CompletableFuture<Object> otherFuture() { 105 return MinimalFuture.completedFuture(new Object()); 106 } 107 relay(Object r, Throwable e)108 private static Object relay(Object r, Throwable e) { 109 if (e != null) 110 throw new CompletionException(e); 111 else 112 return r; 113 } 114 completionStageOf(Object r)115 private static CompletableFuture<?> completionStageOf(Object r) { 116 return new CompletableFuture<>(); 117 } 118 accept(Object arg)119 private static void accept(Object arg) { 120 } 121 accept(Object arg1, Object arg2)122 private static void accept(Object arg1, Object arg2) { 123 } 124 run()125 private static void run() { 126 } 127 apply(Object arg)128 private static Object apply(Object arg) { 129 return new Object(); 130 } 131 apply(Object arg1, Object arg2)132 private static Object apply(Object arg1, Object arg2) { 133 return new Object(); 134 } 135 136 137 @DataProvider(name = "futures") futures()138 public Object[][] futures() { 139 140 MinimalFuture<Object> mf = new MinimalFuture<>(); 141 mf.completeExceptionally(new Throwable()); 142 143 MinimalFuture<Object> mf1 = new MinimalFuture<>(); 144 mf1.complete(new Object()); 145 146 return new Object[][]{ 147 new Object[]{new MinimalFuture<>()}, 148 new Object[]{MinimalFuture.failedFuture(new Throwable())}, 149 new Object[]{MinimalFuture.completedFuture(new Object())}, 150 new Object[]{mf}, 151 new Object[]{mf1}, 152 }; 153 } 154 assertNoObtrusion(CompletableFuture<?> cf)155 private void assertNoObtrusion(CompletableFuture<?> cf) { 156 assertThrows(UnsupportedOperationException.class, 157 () -> cf.obtrudeValue(null)); 158 assertThrows(UnsupportedOperationException.class, 159 () -> cf.obtrudeException(new RuntimeException())); 160 } 161 } 162