1 /*
2  * Copyright (c) 2015, 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  * @bug 8020968
27  * @summary Sanity test for Function wildcard signature
28  * @run main WalkFunction
29  */
30 
31 package test.java.lang.StackWalker;
32 
33 import java.lang.StackWalker.StackFrame;
34 import java.util.Optional;
35 import java.util.function.Function;
36 import java.util.stream.Stream;
37 import org.testng.annotations.Test;
38 
39 public class WalkFunction {
40     private static final StackWalker walker = StackWalker.getInstance();
41 
42     // Android-changed: Add @Test annotation.
43     // public static void main(String... args) throws Exception {
44     @Test
main()45     public static void main() throws Exception {
46         testFunctions();
47         testWildcards();
48         walker.walk(counter());
49         walker.walk(wildCounter());
50     }
51 
testFunctions()52     private static void testFunctions() {
53         walker.walk(Stream::count);
54 
55         try {
56             walker.walk(null);
57             throw new RuntimeException("NPE expected");
58         } catch (NullPointerException e) {}
59 
60         Optional<StackFrame> result = walker.walk(WalkFunction::reduce);
61         if (!result.get().getClassName().equals(WalkFunction.class.getName())) {
62             throw new RuntimeException(result.get() + " expected: " + WalkFunction.class.getName());
63         }
64     }
65 
reduce(Stream<StackFrame> stream)66     static Optional<StackFrame> reduce(Stream<StackFrame> stream) {
67         // Android-changed: Ignore Android test infra classes.
68         // return stream.reduce((r,f) -> r.getClassName().compareTo(f.getClassName()) > 0 ? f : r);
69         return stream.reduce((r,f) -> {
70             String name = f.getClassName();
71 
72             String[] androidInfraPackages = new String[] {
73                 "android.app.Instrumentation",
74                 "androidx.test",
75                 "com.android.cts",
76                 "org.junit",
77                 "org.testng",
78             };
79             for (String pkg : androidInfraPackages) {
80                 if (name.startsWith(pkg)) {
81                     return r;
82                 }
83             }
84             return r.getClassName().compareTo(name) > 0 ? f : r;
85         });
86     }
87 
testWildcards()88     private static void testWildcards() {
89         Function<? super Stream<? extends  StackFrame>, Void> f1 = WalkFunction::function;
90         Function<? super Stream<? super StackFrame>, Void> f2 = WalkFunction::function;
91         Function<? super Stream<StackFrame>, Void> f3 = WalkFunction::function;
92         Function<Stream<? extends StackFrame>, Void> f4 = WalkFunction::function;
93         Function<Stream<? super StackFrame>, Void> f5 = WalkFunction::function;
94         Function<Stream<StackFrame>, Void> f6 = WalkFunction::function;
95         walker.walk(f1);
96         walker.walk(f2);
97         walker.walk(f3);
98         walker.walk(f4);
99         walker.walk(f5);
100         walker.walk(f6);
101     }
102 
function(Stream<?> s)103     private static Void function(Stream<?> s) {
104         return null;
105     }
106 
wildCounter()107     private static Function<Stream<?>, Long> wildCounter() {
108         return Stream::count;
109     }
counter()110     private static <T> Function<Stream<T>, Long> counter() {
111         return Stream::count;
112     }
113 }
114