1/*
2 * Copyright (c) 2015, 2016, 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 8135068
27 * @summary Tests CompilerCommand's method matcher
28 * @modules java.base/jdk.internal.misc
29 * @library /test/lib /
30 *
31 * @build sun.hotspot.WhiteBox
32 * @run driver ClassFileInstaller sun.hotspot.WhiteBox
33 *                                sun.hotspot.WhiteBox$WhiteBoxPermission
34 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
35 *           -XX:+WhiteBoxAPI compiler.compilercontrol.matcher.MethodMatcherTest
36 */
37
38package compiler.compilercontrol.matcher;
39
40import compiler.compilercontrol.share.method.MethodDescriptor;
41import compiler.compilercontrol.share.method.MethodGenerator;
42import compiler.compilercontrol.share.pool.PoolHelper;
43import jdk.test.lib.util.Pair;
44import sun.hotspot.WhiteBox;
45
46import java.lang.reflect.Executable;
47import java.util.ArrayList;
48import java.util.List;
49import java.util.concurrent.Callable;
50import java.util.regex.Matcher;
51import java.util.regex.Pattern;
52
53public class MethodMatcherTest {
54    private static final WhiteBox WB = WhiteBox.getWhiteBox();
55    private static final PoolHelper POOL = new PoolHelper();
56    private static final List<Pair<Executable, Callable<?>>> METHODS =
57            POOL.getAllMethods();
58    private static final int AMOUNT = Integer.parseInt(System
59            .getProperty("test.amount", "25"));
60
61    public static void main(String[] args) {
62        MethodGenerator gen = new MethodGenerator();
63        List<Pair<Executable, Callable<?>>> testMethods =
64                POOL.getAllMethods(PoolHelper.METHOD_FILTER);
65        for (Pair<Executable, Callable<?>> pair : testMethods) {
66            for (int i = 0; i < AMOUNT; i++) {
67                MethodDescriptor md = gen.generateRandomDescriptor(pair.first);
68                check(md);
69            }
70        }
71    }
72
73    /**
74     * Check method matcher with given test case
75     *
76     * @param methodDescriptor method descriptor to check matcher's pattern
77     */
78    private static void check(MethodDescriptor methodDescriptor) {
79        System.out.println("Test case: " + methodDescriptor.getString());
80        System.out.println("Regex: " + methodDescriptor.getRegexp());
81        Pattern pattern = Pattern.compile(methodDescriptor.getRegexp());
82        boolean isValidDesc = methodDescriptor.isValid();
83        List<MethodDescriptor> failList = new ArrayList<>();
84        // walk through all methods in pool to check match with test pattern
85        for (Pair<Executable, Callable<?>> pair : METHODS) {
86            MethodDescriptor m = MethodGenerator.commandDescriptor(pair.first);
87            Matcher matcher = pattern.matcher(m.getCanonicalString());
88            // get expected result
89            MatcherResult expected;
90            if (isValidDesc) {
91                expected = matcher.matches() ?
92                        MatcherResult.MATCH : MatcherResult.NO_MATCH;
93            } else {
94                expected = MatcherResult.PARSING_FAILURE;
95            }
96            // get MethodMatcher's result
97            MatcherResult matchResult = MatcherResult.fromCode(WB.matchesMethod(
98                    pair.first, methodDescriptor.getString()));
99            // compare
100            if (matchResult != expected) {
101                System.out.printf("- Method: %s%n-- FAILED: result: %s, " +
102                                "but expected: %s%n", m.getCanonicalString(),
103                        matchResult, expected);
104                failList.add(m);
105            }
106        }
107        int size = failList.size();
108        if (size != 0) {
109            System.err.println("FAILED test case: " + methodDescriptor
110                    .getString());
111            if (size == METHODS.size()) {
112                System.err.println("-- All methods failed to match");
113            } else {
114                for (MethodDescriptor md : failList) {
115                    System.err.println("-- FAILED match: " + md.getString());
116                }
117            }
118            throw new AssertionError("FAIL: " + methodDescriptor.getString());
119        }
120        System.out.println("--PASSED");
121    }
122
123    /**
124     * Represents MethodMatcher's matching result
125     */
126    public enum MatcherResult {
127        PARSING_FAILURE(-1, "Parsing failed"),
128        NO_MATCH(0, "No match"),
129        MATCH(1, "Match");
130
131        public final int code;
132        private final String message;
133
134        private MatcherResult(int code, String message) {
135            this.code = code;
136            this.message = message;
137        }
138
139        public static MatcherResult fromCode(int code) {
140            switch (code) {
141                case -1: return PARSING_FAILURE;
142                case  0: return NO_MATCH;
143                case  1: return MATCH;
144                default:
145                    throw new IllegalArgumentException("MATCHER FAILURE:"
146                            + "Wrong code: " + code);
147            }
148        }
149
150        @Override
151        public String toString() {
152            return message;
153        }
154    }
155}
156