Path: blob/master/test/jdk/javax/management/generified/GenericTest.java
41149 views
/*1* Copyright (c) 2004, 2020, 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 4847959 619140226* @summary Test newly-generified APIs27* @author Eamonn McManus28*29* @run clean GenericTest30* @run build GenericTest31* @run main GenericTest32*/3334import java.lang.management.ManagementFactory;35import java.lang.reflect.*;36import java.util.*;37import java.util.stream.Stream;38import javax.management.*;39import javax.management.openmbean.*;40import javax.management.relation.*;41import javax.management.timer.Timer;42import javax.management.timer.TimerMBean;4344public class GenericTest {45private static int failures;4647public static void main(String[] args) throws Exception {48MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();4950// Check we are really using the generified version51boolean generic;52Method findmbs = MBeanServerFactory.class.getMethod("findMBeanServer",53String.class);54Type findmbstype = findmbs.getGenericReturnType();55if (!(findmbstype instanceof ParameterizedType)) {56System.out.println("FAILURE: API NOT GENERIC!");57System.out.println(" MBeanServerFactory.findMBeanServer -> " +58findmbstype);59failures++;60generic = false;61} else {62System.out.println("OK: this API is generic");63generic = true;64}6566ArrayList<MBeanServer> mbsList1 =67MBeanServerFactory.findMBeanServer(null);68checked(mbsList1, MBeanServer.class);69ArrayList mbsList2 = MBeanServerFactory.findMBeanServer(null);70check("ArrayList<MBeanServer> findMBeanServer", mbsList1.size() == 1);71check("ArrayList findMBeanServer", mbsList1.equals(mbsList2));7273boolean isSecondAttempt = false;74Set<ObjectName> names1 = null;75while (true) {76names1 = checked(mbs.queryNames(null, null), ObjectName.class);77Set names2 = mbs.queryNames(null, null);78Set<ObjectName> names3 =79checked(((MBeanServerConnection) mbs).queryNames(null, null),80ObjectName.class);81// If new MBean (e.g. Graal MBean) is registered while the test is running, names1,82// names2, and names3 will have different sizes. Repeat the test in this case.83if (sameSize(names1, names2, names3) || isSecondAttempt) {84check("Set<ObjectName> MBeanServer.queryNames", names1.size() >= 1);85check("Set MBeanServer.queryNames", names2.size() >= 1);86check("Set<ObjectName> MBeanServerConnection.queryNames",87names3.size() >= 1);88check("queryNames sets same",89names1.equals(names2) && names2.equals(names3));90break;91}92isSecondAttempt = true;93System.out.println("queryNames sets have different size, retrying...");94}9596isSecondAttempt = false;97while (true) {98Set<ObjectInstance> mbeans1 =99checked(mbs.queryMBeans(null, null), ObjectInstance.class);100Set mbeans2 = mbs.queryMBeans(null, null);101Set<ObjectInstance> mbeans3 =102checked(((MBeanServerConnection) mbs).queryMBeans(null, null),103ObjectInstance.class);104// If new MBean (e.g. Graal MBean) is registered while the test is running, mbeans1,105// mbeans2, and mbeans3 will have different sizes. Repeat the test in this case.106if (sameSize(mbeans1, mbeans2, mbeans3) || isSecondAttempt) {107check("Set<ObjectInstance> MBeanServer.queryMBeans",108mbeans1.size() >= 1);109check("Set MBeanServer.queryMBeans", mbeans2.size() >= 1);110check("Set<ObjectInstance> MBeanServerConnection.queryMBeans",111mbeans3.size() >= 1);112check("queryMBeans sets same",113mbeans1.equals(mbeans2) && mbeans2.equals(mbeans3));114break;115}116isSecondAttempt = true;117System.out.println("queryMBeans sets have different size, retrying...");118}119120AttributeChangeNotificationFilter acnf =121new AttributeChangeNotificationFilter();122acnf.enableAttribute("foo");123Vector<String> acnfs = acnf.getEnabledAttributes();124checked(acnfs, String.class);125check("Vector<String> AttributeChangeNotificationFilter.getEnabled" +126"Attributes", acnfs.equals(Arrays.asList(new String[] {"foo"})));127128if (generic) {129Attribute a = new Attribute("foo", "bar");130AttributeList al1 = new AttributeList();131al1.add(a);132AttributeList al2 =133new AttributeList(Arrays.asList(new Attribute[] {a}));134check("new AttributeList(List<Attribute>)", al1.equals(al2));135List<Attribute> al3 = checked(al1.asList(), Attribute.class);136al3.remove(a);137check("List<Attribute> AttributeList.asList()",138al1.equals(al3) && al1.isEmpty());139}140141List<ObjectName> namelist1 = new ArrayList<ObjectName>(names1);142Role role = new Role("rolename", namelist1);143List<ObjectName> namelist2 =144checked(role.getRoleValue(), ObjectName.class);145check("new Role(String,List<ObjectName>).getRoleValue() -> " +146"List<ObjectName>", namelist1.equals(namelist2));147148RoleList rl1 = new RoleList();149rl1.add(role);150RoleList rl2 = new RoleList(Arrays.asList(new Role[] {role}));151check("new RoleList(List<Role>)", rl1.equals(rl2));152if (generic) {153List<Role> rl3 = checked(rl1.asList(), Role.class);154rl3.remove(role);155check("List<Role> RoleList.asList()",156rl1.equals(rl3) && rl1.isEmpty());157}158159RoleUnresolved ru =160new RoleUnresolved("rolename", namelist1,161RoleStatus.LESS_THAN_MIN_ROLE_DEGREE);162List<ObjectName> namelist3 =163checked(ru.getRoleValue(), ObjectName.class);164check("new RoleUnresolved(...List<ObjectName>...).getRoleValue() -> " +165"List<ObjectName>", namelist1.equals(namelist3));166167RoleUnresolvedList rul1 = new RoleUnresolvedList();168rul1.add(ru);169RoleUnresolvedList rul2 =170new RoleUnresolvedList(Arrays.asList(new RoleUnresolved[] {ru}));171check("new RoleUnresolvedList(List<RoleUnresolved>", rul1.equals(rul2));172if (generic) {173List<RoleUnresolved> rul3 =174checked(rul1.asList(), RoleUnresolved.class);175rul3.remove(ru);176check("List<RoleUnresolved> RoleUnresolvedList.asList()",177rul1.equals(rul3) && rul1.isEmpty());178}179180// This case basically just tests that we can compile this sort of thing181OpenMBeanAttributeInfo ombai1 =182new OpenMBeanAttributeInfoSupport("a", "a descr",183SimpleType.INTEGER,184true, true, false);185CompositeType ct =186new CompositeType("ct", "ct descr", new String[] {"item1"},187new String[] {"item1 descr"},188new OpenType[] {SimpleType.INTEGER});189OpenMBeanAttributeInfo ombai2 =190new OpenMBeanAttributeInfoSupport("a", "a descr",191ct, true, true, false);192TabularType tt =193new TabularType("tt", "tt descr", ct, new String[] {"item1"});194OpenMBeanAttributeInfo ombai3 =195new OpenMBeanAttributeInfoSupport("a", "a descr",196tt, true, true, false);197ArrayType<String[][]> at =198new ArrayType<String[][]>(2, SimpleType.STRING);199OpenMBeanAttributeInfo ombai4 =200new OpenMBeanAttributeInfoSupport("a", "a descr",201at, true, true, false);202OpenMBeanAttributeInfo ombai4a =203new OpenMBeanAttributeInfoSupport("a", "a descr",204(ArrayType) at,205true, true, false);206OpenMBeanAttributeInfo ombai5 =207new OpenMBeanAttributeInfoSupport("a", "a descr",208SimpleType.INTEGER,209true, true, false,2105, 1, 9);211OpenMBeanAttributeInfo ombai6 =212new OpenMBeanAttributeInfoSupport("a", "a descr",213SimpleType.INTEGER,214true, true, false,2155, new Integer[] {1, 5});216217OpenMBeanInfo ombi =218new OpenMBeanInfoSupport("a.a", "a.a descr",219new OpenMBeanAttributeInfo[] {220ombai1, ombai2, ombai3, ombai4,221ombai5, ombai6,222},223null, null, null);224225Map<String,Integer> itemMap =226checked(singletonMap("item1", 5),227String.class, Integer.class);228CompositeData cd =229new CompositeDataSupport(ct, itemMap);230check("CompositeDataSupport(CompositeType, Map<String,?>",231cd.get("item1").equals(5));232233Set<String> ctkeys = checked(ct.keySet(), String.class);234check("Set<String> CompositeType.keySet()",235ctkeys.equals(singleton("item1")));236237List<String> ttindex = checked(tt.getIndexNames(), String.class);238check("Set<String> TabularType.getIndexNames()",239ttindex.equals(singletonList("item1")));240241TabularData td = new TabularDataSupport(tt);242td.putAll(new CompositeData[] {cd});243List<Integer> tdkey = checked(singletonList(5), Integer.class);244Set<List<Integer>> tdkeys = checked(singleton(tdkey),245(Class<List<Integer>>) tdkey.getClass());246Collection<CompositeData> tdvalues = checked(singleton(cd),247CompositeData.class);248check("Set<List<?>> TabularDataSupport.keySet()",249td.keySet().equals(tdkeys));250check("Collection<CompositeData> TabularDataSupport.values()",251td.values().iterator().next().equals(tdvalues.iterator().next()));252253ObjectName stupidName = new ObjectName("stupid:a=b");254mbs.registerMBean(new Stupid(), stupidName);255StupidMBean proxy =256MBeanServerInvocationHandler.newProxyInstance(mbs,257stupidName,258StupidMBean.class,259false);260check("MBeanServerInvocationHandler.newProxyInstance",261proxy.getFive() == 5);262mbs.unregisterMBean(stupidName);263264mbs.registerMBean(new StandardMBean(new Stupid(), StupidMBean.class),265stupidName);266check("<T> StandardMBean(T impl, Class<T> intf)",267proxy.getFive() == 5);268269// Following is based on the package.html for javax.management.relation270// Create the Relation Service MBean271ObjectName relSvcName = new ObjectName(":type=RelationService");272RelationService relSvcObject = new RelationService(true);273mbs.registerMBean(relSvcObject, relSvcName);274275// Create an MBean proxy for easier access to the Relation Service276RelationServiceMBean relSvc =277MBeanServerInvocationHandler.newProxyInstance(mbs, relSvcName,278RelationServiceMBean.class,279false);280281// Define the DependsOn relation type282RoleInfo[] dependsOnRoles = {283new RoleInfo("dependent", Module.class.getName()),284new RoleInfo("dependedOn", Module.class.getName())285};286relSvc.createRelationType("DependsOn", dependsOnRoles);287288// Now define a relation instance "moduleA DependsOn moduleB"289290ObjectName moduleA = new ObjectName(":type=Module,name=A");291ObjectName moduleB = new ObjectName(":type=Module,name=B");292293// Following two lines added to example:294mbs.registerMBean(new Module(), moduleA);295mbs.registerMBean(new Module(), moduleB);296297Role dependent = new Role("dependent", singletonList(moduleA));298Role dependedOn = new Role("dependedOn", singletonList(moduleB));299Role[] roleArray = {dependent, dependedOn};300RoleList roles = new RoleList(Arrays.asList(roleArray));301relSvc.createRelation("A-DependsOn-B", "DependsOn", roles);302303// Query the Relation Service to find what modules moduleA depends on304Map<ObjectName,List<String>> dependentAMap =305relSvc.findAssociatedMBeans(moduleA, "DependsOn", "dependent");306Set<ObjectName> dependentASet = dependentAMap.keySet();307dependentASet = checked(dependentASet, ObjectName.class);308// Set of ObjectName containing moduleB309check("Map<ObjectName,List<String>> RelationService.findAssociatedMBeans",310dependentAMap.size() == 1 &&311dependentASet.equals(singleton(moduleB)));312313Map<String,List<String>> refRels =314relSvc.findReferencingRelations(moduleA, "DependsOn", "dependent");315List<String> refRoles =316checked(refRels.get("A-DependsOn-B"), String.class);317check("Map<String,List<String>> RelationService.findReferencingRelations",318refRoles.equals(singletonList("dependent")));319320List<String> relsOfType = relSvc.findRelationsOfType("DependsOn");321relsOfType = checked(relsOfType, String.class);322check("List<String> RelationService.findRelationsOfType",323relsOfType.equals(singletonList("A-DependsOn-B")));324325List<String> allRelIds = relSvc.getAllRelationIds();326allRelIds = checked(allRelIds, String.class);327check("List<String> RelationService.getAllRelationIds()",328allRelIds.equals(singletonList("A-DependsOn-B")));329330List<String> allRelTypes = relSvc.getAllRelationTypeNames();331allRelTypes = checked(allRelTypes, String.class);332check("List<String> RelationService.getAllRelationTypeNames",333allRelTypes.equals(singletonList("DependsOn")));334335Map<ObjectName,List<String>> refdMBeans =336relSvc.getReferencedMBeans("A-DependsOn-B");337check("Map<ObjectName,List<String>> RelationService.getReferencedMBeans",338refdMBeans.get(moduleA).equals(singletonList("dependent")) &&339refdMBeans.get(moduleB).equals(singletonList("dependedOn")));340341List<ObjectName> roleContents =342checked(relSvc.getRole("A-DependsOn-B", "dependent"),343ObjectName.class);344check("List<ObjectName> RelationService.getRole",345roleContents.equals(singletonList(moduleA)));346347RoleInfo roleInfoDependent =348relSvc.getRoleInfo("DependsOn", "dependent");349RoleInfo roleInfoDependedOn =350relSvc.getRoleInfo("DependsOn", "dependedOn");351List<RoleInfo> expectedRoleInfos =352Arrays.asList(new RoleInfo[] {roleInfoDependent, roleInfoDependedOn});353List<RoleInfo> roleInfos =354checked(relSvc.getRoleInfos("DependsOn"), RoleInfo.class);355check("List<RoleInfo> RelationService.getRoleInfos",356equalListContents(expectedRoleInfos, roleInfos));357358RelationType relType =359new RelationTypeSupport("DependsOn", dependsOnRoles);360List<RoleInfo> relTypeRoleInfos =361checked(relType.getRoleInfos(), RoleInfo.class);362// Since there's no RoleInfo.equals and since the RelationTypeSupport363// constructor clones the RoleInfos passed to it, it's tricky to364// test equality here so we check type and size and have done with it365check("List<RoleInfo> RelationType.getRoleInfos",366relTypeRoleInfos.size() == 2);367368MBeanServerNotificationFilter mbsnf =369new MBeanServerNotificationFilter();370mbsnf.enableObjectName(moduleA);371check("Vector<ObjectName> MBeanServerNotificationFilter." +372"getEnabledObjectNames",373mbsnf.getEnabledObjectNames().equals(Arrays.asList(moduleA)));374mbsnf.enableAllObjectNames();375mbsnf.disableObjectName(moduleB);376check("Vector<ObjectName> MBeanServerNotificationFilter." +377"getDisabledObjectNames",378mbsnf.getDisabledObjectNames().equals(Arrays.asList(moduleB)));379380RelationService unusedRelSvc = new RelationService(false);381RelationNotification rn1 =382new RelationNotification(RelationNotification.RELATION_MBEAN_REMOVAL,383unusedRelSvc, 0L, 0L, "yo!",384"A-DependsOn-B", "DependsOn", null,385singletonList(moduleA));386List<ObjectName> toUnreg =387checked(rn1.getMBeansToUnregister(), ObjectName.class);388check("List<ObjectName> RelationNotification.getMBeansToUnregister",389toUnreg.equals(singletonList(moduleA)));390391RelationNotification rn2 =392new RelationNotification(RelationNotification.RELATION_MBEAN_UPDATE,393unusedRelSvc, 0L, 0L, "yo!",394"A-DependsOn-B", "DependsOn", null,395"dependent", singletonList(moduleA),396singletonList(moduleB));397check("List<ObjectName> RelationNotification.getOldRoleValue",398checked(rn2.getOldRoleValue(), ObjectName.class)399.equals(singletonList(moduleB)));400check("List<ObjectName> RelationNotification.getNewRoleValue",401checked(rn2.getNewRoleValue(), ObjectName.class)402.equals(singletonList(moduleA)));403404ObjectName timerName = new ObjectName(":type=timer");405mbs.registerMBean(new Timer(), timerName);406TimerMBean timer =407MBeanServerInvocationHandler.newProxyInstance(mbs,408timerName,409TimerMBean.class,410false);411Date doomsday = new Date(Long.MAX_VALUE);412int timer1 = timer.addNotification("one", "one", null, doomsday);413int timer2 = timer.addNotification("two", "two", null, doomsday);414Vector<Integer> idsOne = timer.getNotificationIDs("one");415check("Vector<Integer> TimerMBean.getNotificationIDs",416idsOne.equals(singletonList(timer1)));417Vector<Integer> allIds = timer.getAllNotificationIDs();418check("Vector<Integer> TimerMBean.getAllNotificationIDs",419equalListContents(allIds,420Arrays.asList(new Integer[]{timer1, timer2})));421422// ADD NEW TEST CASES ABOVE THIS COMMENT423424if (failures == 0)425System.out.println("All tests passed");426else {427System.out.println("TEST FAILURES: " + failures);428System.exit(1);429}430431// DO NOT ADD NEW TEST CASES HERE, ADD THEM ABOVE THE PREVIOUS COMMENT432}433434public static interface StupidMBean {435public int getFive();436}437438public static class Stupid implements StupidMBean {439public int getFive() {440return 5;441}442}443444public static class Module extends StandardMBean implements StupidMBean {445public Module() throws NotCompliantMBeanException {446super(StupidMBean.class);447}448449public int getFive() {450return 5;451}452}453454private static <E> List<E> singletonList(E value) {455return Collections.singletonList(value);456}457458private static <E> Set<E> singleton(E value) {459return Collections.singleton(value);460}461462private static <K,V> Map<K,V> singletonMap(K key, V value) {463return Collections.singletonMap(key, value);464}465466private static <E> List<E> checked(List<E> c, Class<E> type) {467List<E> unchecked = new ArrayList<E>();468List<E> checked = Collections.checkedList(unchecked, type);469checked.addAll(c);470return Collections.checkedList(c, type);471}472473private static <E> Set<E> checked(Set<E> c, Class<E> type) {474Set<E> unchecked = new HashSet<E>();475Set<E> checked = Collections.checkedSet(unchecked, type);476checked.addAll(c);477return Collections.checkedSet(c, type);478}479480private static <K,V> Map<K,V> checked(Map<K,V> m,481Class<K> keyType,482Class<V> valueType) {483Map<K,V> unchecked = new HashMap<K,V>();484Map<K,V> checked = Collections.checkedMap(unchecked, keyType, valueType);485checked.putAll(m);486return Collections.checkedMap(m, keyType, valueType);487}488489/* The fact that we have to call this method is a clear signal that490* the API says List where it means Set.491*/492private static <E> boolean equalListContents(List<E> l1, List<E> l2) {493return new HashSet<E>(l1).equals(new HashSet<E>(l2));494}495496private static void check(String what, boolean cond) {497if (cond)498System.out.println("OK: " + what);499else {500System.out.println("FAILED: " + what);501failures++;502}503}504505private static boolean sameSize(Set ... sets) {506return Stream.of(sets).map(s -> s.size()).distinct().count() == 1;507}508}509510511