Path: blob/master/test/jdk/javax/management/openmbean/BadConstraintTest.java
41149 views
/*1* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 620446926* @summary Test that Open MBean attributes and parameters cannot have27* illegal constraints like min greater than max28* @author Eamonn McManus29*30* @run clean BadConstraintTest31* @run build BadConstraintTest32* @run main BadConstraintTest33*/3435import java.io.*;36import java.lang.reflect.*;37import java.util.*;38import javax.management.*;39import javax.management.openmbean.*;4041public class BadConstraintTest {42private static String failure;4344public static void main(String[] args) throws Exception {45genericTests();46descriptorTests();4748if (failure == null)49System.out.println("Test passed");50else51throw new Exception("TEST FAILED: " + failure);52}5354private static void genericTests() throws Exception {55for (Object[] test : tests) {56if (test.length != 5) {57throw new Exception("Test element has wrong length: " +58toString(test));59}6061OpenType<?> openType = (OpenType<?>) test[0];62Object defaultValue = test[1];63Comparable<?> minValue = (Comparable<?>) test[2];64Comparable<?> maxValue = (Comparable<?>) test[3];65Object[] legalValues = (Object[]) test[4];6667System.out.println("test: openType=" + openType +68"; defaultValue=" + defaultValue +69"; minValue=" + minValue +70"; maxValue=" + maxValue +71"; legalValues=" + toString(legalValues));7273genericTest(openType, defaultValue, minValue, maxValue,74legalValues);75}76}7778private static void descriptorTests() throws Exception {79for (Object[][] test : descriptorTests) {80if (test.length != 2) {81throw new Exception("Test element has wrong length: " +82toString(test));83}8485if (test[0].length != 1) {86throw new Exception("Test element should have one OpenType: " +87toString(test[0]));88}8990OpenType<?> openType = (OpenType<?>) test[0][0];91Descriptor d = descriptor(test[1]);9293System.out.println("test: openType=" + openType +94"; descriptor=" + d);9596descriptorTest(openType, d);97}98}99100/* Tests that apply to both the Descriptor and the non-Descriptor101constructors. We invoke the non-Descriptor constructors by102reflection, then we make the corresponding Descriptor and call103the descriptorTest with it. */104private static void genericTest(OpenType<?> openType,105Object defaultValue,106Comparable<?> minValue,107Comparable<?> maxValue,108Object[] legalValues)109throws Exception {110111if (minValue == null && maxValue == null && legalValues == null) {112if (defaultValue == null)113throw new Exception("What am I testing?");114Class[] params1 = new Class[] {115String.class, String.class, OpenType.class,116boolean.class, boolean.class, boolean.class,117Object.class118};119Constructor<OpenMBeanAttributeInfoSupport> c1 =120OpenMBeanAttributeInfoSupport.class.getConstructor(params1);121Class[] params2 = new Class[] {122String.class, String.class, OpenType.class,123Object.class124};125Constructor<OpenMBeanParameterInfoSupport> c2 =126OpenMBeanParameterInfoSupport.class.getConstructor(params2);127ode(c1, "name", "descr", openType, true, true, false, defaultValue);128ode(c2, "name", "descr", openType, defaultValue);129descriptorTest(openType,130descriptor("defaultValue", defaultValue));131descriptorTest(openType,132descriptor("defaultValue", string(defaultValue)));133}134135if (legalValues == null) {136Class[] params1 = new Class[] {137String.class, String.class, OpenType.class,138boolean.class, boolean.class, boolean.class,139Object.class, Comparable.class, Comparable.class140};141Constructor<OpenMBeanAttributeInfoSupport> c1 =142OpenMBeanAttributeInfoSupport.class.getConstructor(params1);143Class[] params2 = new Class[] {144String.class, String.class, OpenType.class,145Object.class, Comparable.class, Comparable.class146};147Constructor<OpenMBeanParameterInfoSupport> c2 =148OpenMBeanParameterInfoSupport.class.getConstructor(params2);149ode(c1, "name", "descr", openType, true, true, false, defaultValue,150minValue, maxValue);151ode(c2, "name", "descr", openType, defaultValue,152minValue, maxValue);153descriptorTest(openType,154descriptor("defaultValue", defaultValue,155"minValue", minValue,156"maxValue", maxValue));157descriptorTest(openType,158descriptor("defaultValue", string(defaultValue),159"minValue", string(minValue),160"maxValue", string(maxValue)));161}162163if (legalValues != null) {164Class[] params1 = new Class[] {165String.class, String.class, OpenType.class,166boolean.class, boolean.class, boolean.class,167Object.class, Object[].class168};169Constructor<OpenMBeanAttributeInfoSupport> c1 =170OpenMBeanAttributeInfoSupport.class.getConstructor(params1);171Class[] params2 = new Class[] {172String.class, String.class, OpenType.class,173Object.class, Object[].class174};175Constructor<OpenMBeanParameterInfoSupport> c2 =176OpenMBeanParameterInfoSupport.class.getConstructor(params2);177ode(c1, "name", "descr", openType, true, true, false, defaultValue,178legalValues);179ode(c2, "name", "descr", openType, defaultValue,180legalValues);181descriptorTest(openType,182descriptor("defaultValue", defaultValue,183"legalValues", legalValues));184descriptorTest(openType,185descriptor("defaultValue", defaultValue,186"legalValues", arraySet(legalValues)));187Set<String> strings = new HashSet<String>();188for (Object x : legalValues)189strings.add(x.toString());190descriptorTest(openType,191descriptor("defaultValue", defaultValue,192"legalValues", strings));193descriptorTest(openType,194descriptor("defaultValue", defaultValue,195"legalValues",196strings.toArray(new String[0])));197}198}199200private static void descriptorTest(OpenType<?> openType, Descriptor d)201throws Exception {202Class[] params1 = new Class[] {203String.class, String.class, OpenType.class,204boolean.class, boolean.class, boolean.class,205Descriptor.class206};207Constructor<OpenMBeanAttributeInfoSupport> c1 =208OpenMBeanAttributeInfoSupport.class.getConstructor(params1);209Class[] params2 = new Class[] {210String.class, String.class, OpenType.class,211Descriptor.class212};213Constructor<OpenMBeanParameterInfoSupport> c2 =214OpenMBeanParameterInfoSupport.class.getConstructor(params2);215iae(c1, "name", "descr", openType, true, true, false, d);216iae(c2, "name", "descr", openType, d);217}218219/* Check that the given constructor invocation gets an220IllegalArgumentException. */221private static void iae(Constructor<?> con, Object... params) {222checkException(IllegalArgumentException.class, con, params);223}224225/* Check that the given constructor invocation gets an226OpenDataException. */227private static void ode(Constructor<?> con, Object... params) {228checkException(OpenDataException.class, con, params);229}230231private static void checkException(Class<? extends Exception> exc,232Constructor<?> con, Object[] params) {233try {234con.newInstance(params);235fail("Constructor succeeded but should have got " + exc.getName() +236" with params " + Arrays.deepToString(params));237} catch (InvocationTargetException e) {238Throwable cause = e.getCause();239if (exc.isInstance(cause))240return;241StringWriter sw = new StringWriter();242PrintWriter pw = new PrintWriter(sw);243cause.printStackTrace(pw);244pw.close();245fail("Constructor should have got " + exc.getName() +246" with params " + Arrays.deepToString(params) + ": " + sw);247} catch (Exception e) {248throw new IllegalArgumentException("Reflection failed", e);249}250}251252private static void fail(String why) {253System.out.println("FAILED: " + why);254failure = why;255}256257private static Descriptor descriptor(Object... entries) {258if (entries.length % 2 != 0)259throw new RuntimeException("Odd length descriptor entries");260String[] names = new String[entries.length / 2];261Object[] values = new Object[entries.length / 2];262for (int i = 0; i < entries.length; i += 2) {263names[i / 2] = (String) entries[i];264values[i / 2] = entries[i + 1];265}266return new ImmutableDescriptor(names, values);267}268269private static <T> Set<T> arraySet(T[] array) {270return new HashSet<T>(Arrays.asList(array));271}272273private static String toString(Object x) {274if (x == null)275return "null";276else if (x.getClass().isArray()) {277StringBuilder sb = new StringBuilder("[");278int len = Array.getLength(x);279for (int i = 0; i < len; i++) {280if (i > 0)281sb.append(", ");282sb.append(toString(Array.get(x, i)));283}284sb.append("]");285return sb.toString();286} else287return x.toString();288}289290private static String string(Object x) {291if (x == null)292return null;293return toString(x);294}295296private static final OpenType<?>297ostring = SimpleType.STRING,298oint = SimpleType.INTEGER,299obool = SimpleType.BOOLEAN,300olong = SimpleType.LONG,301obyte = SimpleType.BYTE,302ofloat = SimpleType.FLOAT,303odouble = SimpleType.DOUBLE,304ostringarray, ostringarray2;305private static final CompositeType ocomposite;306private static final CompositeData compositeData, compositeData2;307static {308try {309ostringarray = new ArrayType<String[]>(1, ostring);310ostringarray2 = new ArrayType<String[][]>(2, ostring);311ocomposite =312new CompositeType("name", "descr",313new String[] {"s", "i"},314new String[] {"sdesc", "idesc"},315new OpenType[] {ostring, oint});316compositeData =317new CompositeDataSupport(ocomposite,318new String[] {"s", "i"},319new Object[] {"foo", 23});320compositeData2 =321new CompositeDataSupport(ocomposite,322new String[] {"s", "i"},323new Object[] {"bar", -23});324} catch (OpenDataException e) { // damn checked exceptions...325throw new IllegalArgumentException(e.toString(), e);326}327}328329private static final Descriptor330nullD = null,331emptyD = ImmutableDescriptor.EMPTY_DESCRIPTOR;332333/* Each element of this array contains five Objects:334- OpenType;335- defaultValue;336- minValue;337- maxValue;338- legalValues. The objects are used to construct tests cases339where all possible constructors that make sense for that340combination of values are invoked, and all are checked to ensure341that they throw the right exception. */342private static final Object[][] tests = {343344// Values must be of appropriate type345346{oint, "oops", null, null, null},347{oint, Long.MAX_VALUE, null, null, null},348{oint, null, "oops", null, null},349{oint, "oops", 3, null, null},350{oint, 3, "oops", null, null},351{oint, null, null, "oops", null},352{oint, null, 3, "oops", null},353{oint, null, 3, false, null},354{oint, null, null, null, new String[] {"x"}},355{oint, null, null, null, new Object[] {"x"}},356{oint, null, null, null, new Object[] {3, "x"}},357358// If defaultValue is present then it must satisfy the constraints359// defined by legalValues, minValue, or maxValue when any of360// these is also present361362{oint, 3, 4, null, null},363{oint, 3, null, 2, null},364{oint, 3, null, null, new Integer[] {2, 4}},365366// If minValue and maxValue are both present then minValue must367// not be greater than maxValue368369{ostring, null, "z", "a", null},370{oint, null, 3, 2, null},371372// We don't support default values or legal sets for arrays (yet)373374{ostringarray, new String[] {"x"}, null, null, null},375{ostringarray, null, null, null, new String[][]{new String[] {"x"}}},376};377378/* The tests here can only be expressed via Descriptors because an379attempt to invoke one of the non-Descriptor constructors with380the implied parameters would not compile (or would fail at the381reflection stage when reflection is being used).382383Each element of this array contains two subarrays. The first384is an array of OpenTypes that must contain exactly one element.385The second is an array of alternating field names and field386values that will be used to construct a Descriptor that is supposed387to fail when given to an OpenMBean*Info constructor with the given388OpenType. */389private static final Object[][][] descriptorTests = {390391// Values must be of appropriate type392393{{oint},394{"minValue", 25L}},395396{{oint},397{"minValue", new Object()}}, // not even Comparable398{{oint},399{"maxValue", new Object()}}, // not even Comparable400{{oint},401{"defaultValue", 3,402"minValue", new Object()}},403{{oint},404{"defaultValue", 3,405"maxValue", new Object()}},406407{{oint},408{"legalValues", new int[] {3}}}, // should be new Integer[] to work409{{oint},410{"legalValues", 3}},411412// If legalValues is present then neither minValue nor maxValue413// must be present414415{{oint},416{"minValue", 3, "legalValues", new Integer[] {3, 4}}},417{{oint},418{"maxValue", 3, "legalValues", new Integer[] {2, 3}}},419{{oint},420{"defaultValue", 3, "minValue", 3, "legalValues", new Integer[] {3}}},421422// We don't support min or max arrays (what would they mean?)423424{{ostringarray},425{"minValue", new String[] {"x"}}},426{{ostringarray},427{"maxValue", new String[] {"x"}}},428429};430}431432433