1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * 
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * The contents of this file are subject to the terms of either the Universal Permissive License
   7  * v 1.0 as shown at http://oss.oracle.com/licenses/upl
   8  *
   9  * or the following license:
  10  *
  11  * Redistribution and use in source and binary forms, with or without modification, are permitted
  12  * provided that the following conditions are met:
  13  * 
  14  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions
  15  * and the following disclaimer.
  16  * 
  17  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
  18  * conditions and the following disclaimer in the documentation and/or other materials provided with
  19  * the distribution.
  20  * 
  21  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
  22  * endorse or promote products derived from this software without specific prior written permission.
  23  * 
  24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  26  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
  31  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 package org.openjdk.jmc.common.test;
  34 
  35 import static org.junit.Assert.assertArrayEquals;
  36 
  37 import java.util.Arrays;
  38 
  39 import org.junit.Assert;
  40 import org.junit.Assume;
  41 import org.openjdk.jmc.common.util.StringToolkit;
  42 import org.openjdk.jmc.common.version.JavaVMVersionToolkit;
  43 import org.openjdk.jmc.common.version.JavaVersion;
  44 import org.openjdk.jmc.common.version.JavaVersionSupport;
  45 
  46 /**
  47  * TestCase extended with convenience assert methods.
  48  */
  49 @SuppressWarnings("nls")
  50 public class MCTestCase {
  51         /**
  52          * Shadowing {@link Assert#assertNull(String, Object)} to provide a more useful error message.
  53          */
  54         static public void assertNull(String message, Object object) {
  55                 if (object != null) {
  56                         failNotEquals(message, null, object);
  57                 }
  58         }
  59 
  60         /**
  61          * Shadowing {@link Assert#assertNull(Object)} to provide a more useful error message.
  62          */
  63         static public void assertNull(Object object) {
  64                 if (object != null) {
  65                         failNotEquals(null, null, object);
  66                 }
  67         }
  68 
  69         static public void failNotEquals(String message, Object expected, Object actual) {
  70                 if (!expected.equals(actual)) {
  71                         Assert.fail(
  72                                         ((message != null) ? message + ' ' : "") + "expected:<" + expected + "> but was:<" + actual + ">");
  73                 }
  74         }
  75 
  76         /**
  77          * Asserts that with respect to all bits in the mask, a long is equal to the given value. If it
  78          * is not an AssertionFailedError is thrown with the given message.
  79          */
  80         static public void assertMaskedEquals(String message, long expected, long actual, long mask) {
  81                 if (((expected ^ actual) & mask) != 0) {
  82                         Assert.fail(((message != null) ? message + ' ' : "")
  83                                         + "masked with " + hex(mask) + " expected:<" + hex(expected) + "> was not:<" + hex(actual) + ">");
  84                 }
  85         }
  86 
  87         /**
  88          * Asserts that with respect to all bits in the mask, a long is equal to the given value.
  89          */
  90         static public void assertMaskedEquals(long expected, long actual, long mask) {
  91                 assertMaskedEquals(null, expected, actual, mask);
  92         }
  93 
  94         protected static String hex(long val) {
  95                 return "0x" + Long.toHexString(val);
  96         }
  97 
  98         /**
  99          * Asserts that a {@link Comparable} is within the given (inclusive) range. If it is not an
 100          * AssertionFailedError is thrown with the given message.
 101          */
 102         static public <T extends Comparable<T>> void assertBetween(String message, T min, T max, T actual) {
 103                 if ((min.compareTo(actual) > 0) || (max.compareTo(actual) < 0)) {
 104                         Assert.fail(((message != null) ? message + ' ' : "")
 105                                         + "expected in:[" + min + ", " + max + "] was not:<" + actual + ">");
 106                 }
 107         }
 108 
 109         /**
 110          * Asserts that a {@link Comparable} is within the given (inclusive) range.
 111          */
 112         static public <T extends Comparable<T>> void assertBetween(T min, T max, T actual) {
 113                 assertBetween(null, min, max, actual);
 114         }
 115 
 116         /**
 117          * Asserts that a {@link Comparable} is less or equal than the given value. If it is not an
 118          * AssertionFailedError is thrown with the given message.
 119          */
 120         static public <T extends Comparable<T>> void assertMax(String message, T max, T actual) {
 121                 if (max.compareTo(actual) < 0) {
 122                         Assert.fail(((message != null) ? message + ' ' : "")
 123                                         + "expected max:<" + max + "> was not:<" + actual + ">");
 124                 }
 125         }
 126 
 127         /**
 128          * Asserts that a {@link Comparable} is less or equal than the given value.
 129          */
 130         static public <T extends Comparable<T>> void assertMax(T max, T actual) {
 131                 assertMax(null, max, actual);
 132         }
 133 
 134         /**
 135          * Asserts that a {@link Comparable} is greater or equal than the given value. If it is not an
 136          * AssertionFailedError is thrown with the given message.
 137          */
 138         static public <T extends Comparable<T>> void assertMin(String message, T min, T actual) {
 139                 if (min.compareTo(actual) > 0) {
 140                         Assert.fail(((message != null) ? message + ' ' : "")
 141                                         + "expected min:<" + min + "> was not:<" + actual + ">");
 142                 }
 143         }
 144 
 145         /**
 146          * Asserts that a {@link Comparable} is greater or equal than the given value.
 147          */
 148         static public <T extends Comparable<T>> void assertMin(T min, T actual) {
 149                 assertMin(null, min, actual);
 150         }
 151 
 152         /**
 153          * Asserts that a {@link Comparable} is less than the given value. If it is not an
 154          * AssertionFailedError is thrown with the given message.
 155          */
 156         static public <T extends Comparable<T>> void assertLessThan(String message, T greaterVal, T actual) {
 157                 if (greaterVal.compareTo(actual) <= 0) {
 158                         Assert.fail(((message != null) ? message + ' ' : "")
 159                                         + "expected less than:<" + greaterVal + "> was not:<" + actual + ">");
 160                 }
 161         }
 162 
 163         /**
 164          * Asserts that a {@link Comparable} is less than the given value.
 165          */
 166         static public <T extends Comparable<T>> void assertLessThan(T greaterVal, T actual) {
 167                 assertLessThan(null, greaterVal, actual);
 168         }
 169 
 170         /**
 171          * Asserts that a {@link Comparable} is greater than the given value. If it is not an
 172          * AssertionFailedError is thrown with the given message.
 173          */
 174         static public <T extends Comparable<? super T>> void assertGreaterThan(String message, T lesserVal, T actual) {
 175                 if (lesserVal.compareTo(actual) >= 0) {
 176                         Assert.fail(((message != null) ? message + ' ' : "")
 177                                         + "expected greater than:<" + lesserVal + "> was not:<" + actual + ">");
 178                 }
 179         }
 180 
 181         /**
 182          * Asserts that a {@link Comparable} is greater than the given value.
 183          */
 184         static public <T extends Comparable<? super T>> void assertGreaterThan(T lesserVal, T actual) {
 185                 assertGreaterThan(null, lesserVal, actual);
 186         }
 187 
 188         public static void assertArrayEqualsWithMoreInfo(String message, Object[] expecteds, Object[] actuals) {
 189                 try {
 190                         assertArrayEquals(message, expecteds, actuals);
 191                 } catch (AssertionError e) {
 192                         StringBuilder sb = new StringBuilder();
 193                         sb.append(e.getMessage());
 194                         sb.append(" (Expected {");
 195                         sb.append(StringToolkit.join(Arrays.asList(expecteds), ", ")).append("}");
 196                         sb.append(", got {");
 197                         sb.append(StringToolkit.join(Arrays.asList(actuals), ", ")).append("}");
 198                         throw new AssertionError(sb.toString(), e);
 199                 }
 200         }
 201 
 202         protected void skipIfEarlierThan8u0() {
 203                 Assume.assumeTrue("This feature is only valid on JDK8u0 or later.",
 204                                 (getClientVersion().compareTo(JVMVersion.JDK8)) >= 0);
 205         }
 206 
 207         protected void skipIfEarlierThan7u40() {
 208                 Assume.assumeTrue("This feature is only valid on JDK7u40 or later.",
 209                                 (getClientVersion().compareTo(JVMVersion.JDK7u40)) >= 0);
 210         }
 211 
 212         protected void skipIfEarlierThan7u4() {
 213                 Assume.assumeTrue("This feature is only valid on JDK7u4 or later.",
 214                                 (getClientVersion().compareTo(JVMVersion.JDK7u4)) >= 0);
 215         }
 216 
 217         protected void skipIfEarlierThan7u0() {
 218                 Assume.assumeTrue("This feature is only valid on JDK7u0 or later.",
 219                                 (getClientVersion().compareTo(JVMVersion.JDK7)) >= 0);
 220         }
 221 
 222         // This enum needs to be in the proper order.
 223         private enum JVMVersion {
 224                 ANY, UNKNOWN, JRockit, JDK6, JDK7, JDK7u4, JDK7u40, JDK8
 225         }
 226 
 227         private JVMVersion getClientVersion() {
 228                 if (JavaVMVersionToolkit.isJRockitJVMName(System.getProperty("java.vm.name"))) {
 229                         return JVMVersion.JRockit;
 230                 } else if (JavaVMVersionToolkit.isHotspotJVMName(System.getProperty("java.vm.name"))) {
 231                         JavaVersion javaVersion = new JavaVersion(System.getProperty("java.version"));
 232                         if (javaVersion.isGreaterOrEqualThan(JavaVersionSupport.JDK_8)) {
 233                                 return JVMVersion.JDK8;
 234                         } else if (javaVersion.isGreaterOrEqualThan(JavaVersionSupport.JDK_7_U_40)) {
 235                                 return JVMVersion.JDK7u40;
 236                         } else if (javaVersion.isGreaterOrEqualThan(JavaVersionSupport.JDK_7_U_4)) {
 237                                 return JVMVersion.JDK7u4;
 238                         } else if (javaVersion.isGreaterOrEqualThan(JavaVersionSupport.JDK_7)) {
 239                                 return JVMVersion.JDK7;
 240                         } else if (javaVersion.isGreaterOrEqualThan(JavaVersionSupport.JDK_6)) {
 241                                 return JVMVersion.JDK6;
 242                         }
 243                 }
 244                 return JVMVersion.UNKNOWN;
 245         }
 246 }