1 /*
   2  * Copyright (c) 2014, 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 import java.util.List;
  26 import java.util.LinkedList;
  27 
  28 import com.oracle.java.testlibrary.ExitCode;
  29 import com.oracle.java.testlibrary.cli.*;
  30 import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
  31 import rtm.predicate.SupportedCPU;
  32 import rtm.predicate.SupportedVM;
  33 
  34 /**
  35  * Base for all RTM-related CLI tests on options whose processing depends
  36  * on UseRTMLocking value.
  37  *
  38  * Since UseRTMLocking option could be used when both CPU and VM supports RTM
  39  * locking, this test will be skipped on all unsupported configurations.
  40  */
  41 public abstract class RTMLockingAwareTest
  42         extends RTMGenericCommandLineOptionTest {
  43     protected final String warningMessage;
  44     protected final String[] correctValues;
  45     protected final String[] incorrectValues;
  46     /**
  47      * Constructs new test for option {@code optionName} that should be executed
  48      * only on CPU with RTM support.
  49      * Test will be executed using set of correct values from
  50      * {@code correctValues} and set of incorrect values from
  51      * {@code incorrectValues}.
  52      *
  53      * @param optionName name of option to be tested
  54      * @param isBoolean {@code true} if tested option is binary
  55      * @param isExperimental {@code true} if tested option is experimental
  56      * @param defaultValue default value of tested option
  57      * @param correctValues array with correct values, that should not emit
  58      *                      {@code warningMessage} to VM output
  59      * @param incorrectValues array with incorrect values, that should emit
  60      *                        {@code waningMessage} to VM output
  61      * @param warningMessage warning message associated with tested option
  62      */
  63     protected RTMLockingAwareTest(String optionName, boolean isBoolean,
  64             boolean isExperimental, String defaultValue,
  65             String[] correctValues, String[] incorrectValues,
  66             String warningMessage) {
  67         super(new AndPredicate(new SupportedCPU(), new SupportedVM()),
  68                 optionName, isBoolean, isExperimental, defaultValue);
  69         this.correctValues = correctValues;
  70         this.incorrectValues = incorrectValues;
  71         this.warningMessage = warningMessage;
  72     }
  73 
  74     @Override
  75     protected void verifyJVMStartup() throws Throwable {
  76         // Run generic sanity checks
  77         super.verifyJVMStartup();
  78         // Verify how option values will be processed depending on
  79         // UseRTMLocking value.
  80         if (correctValues != null) {
  81             for (String correctValue : correctValues) {
  82                 // For correct values it is expected to see no warnings
  83                 // regardless to UseRTMLocking
  84                 verifyStartupWarning(correctValue, true, false);
  85                 verifyStartupWarning(correctValue, false, false);
  86             }
  87         }
  88 
  89         if (incorrectValues != null) {
  90             for (String incorrectValue : incorrectValues) {
  91                 // For incorrect values it is expected to see warning
  92                 // only with -XX:+UseRTMLocking
  93                 verifyStartupWarning(incorrectValue, true, true);
  94                 verifyStartupWarning(incorrectValue, false, false);
  95             }
  96         }
  97     }
  98 
  99     @Override
 100     protected void verifyOptionValues() throws Throwable {
 101         super.verifyOptionValues();
 102         // Verify how option values will be setup after processing
 103         // depending on UseRTMLocking value
 104         if (correctValues != null) {
 105             for (String correctValue : correctValues) {
 106                 // Correct value could be set up regardless to UseRTMLocking
 107                 verifyOptionValues(correctValue, false, correctValue);
 108                 verifyOptionValues(correctValue, true, correctValue);
 109             }
 110         }
 111 
 112         if (incorrectValues != null) {
 113             for (String incorrectValue : incorrectValues) {
 114                 // With -XX:+UseRTMLocking, incorrect value will be changed to
 115                 // default value.
 116                 verifyOptionValues(incorrectValue, false, incorrectValue);
 117                 verifyOptionValues(incorrectValue, true, defaultValue);
 118             }
 119         }
 120     }
 121 
 122     private void verifyStartupWarning(String value, boolean useRTMLocking,
 123             boolean isWarningExpected) throws Throwable {
 124         String warnings[] = new String[] { warningMessage };
 125         List<String> options = new LinkedList<>();
 126         options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
 127                 useRTMLocking));
 128 
 129         if (isExperimental) {
 130             options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
 131         }
 132         options.add(prepareOptionValue(value));
 133 
 134         CommandLineOptionTest.verifySameJVMStartup(
 135                 (isWarningExpected ? warnings : null),
 136                 (isWarningExpected ? null : warnings),
 137                 ExitCode.OK, options.toArray(new String[options.size()]));
 138     }
 139 
 140     private void verifyOptionValues(String value, boolean useRTMLocking,
 141             String expectedValue) throws Throwable {
 142         List<String> options = new LinkedList<>();
 143         options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
 144                 useRTMLocking));
 145 
 146         if (isExperimental) {
 147             options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
 148         }
 149         options.add(prepareOptionValue(value));
 150 
 151         CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
 152                 expectedValue, options.toArray(new String[options.size()]));
 153     }
 154 }