blob: 52eedee7f17e75ec4d5d3a24e1bdabd37e859ecc [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 6252592 4967755
27 * @summary Check that default fields are correctly added to Descriptors
28 * and that input Descriptors are never modified
29 * @author Lars Westergren
30 */
31
32import java.lang.reflect.Constructor;
33import java.lang.reflect.InvocationTargetException;
34import java.lang.reflect.Method;
35import javax.management.Descriptor;
36import javax.management.IntrospectionException;
37import javax.management.MBeanAttributeInfo;
38import javax.management.MBeanConstructorInfo;
39import javax.management.MBeanException;
40import javax.management.MBeanNotificationInfo;
41import javax.management.MBeanOperationInfo;
42import javax.management.RuntimeOperationsException;
43import javax.management.modelmbean.DescriptorSupport;
44import javax.management.modelmbean.ModelMBeanAttributeInfo;
45import javax.management.modelmbean.ModelMBeanConstructorInfo;
46import javax.management.modelmbean.ModelMBeanInfo;
47import javax.management.modelmbean.ModelMBeanInfoSupport;
48import javax.management.modelmbean.ModelMBeanNotificationInfo;
49import javax.management.modelmbean.ModelMBeanOperationInfo;
50
51/**
52 * Junit tests for bugs:
53 * 6252592 Provide for the user mandatory fields missing in Descriptor given
54 * to Model*Info constructors
55 * 4967755 ModelMBeanAttributeInfo constructor modifies its Descriptor argument
56 *
57 * @author Lars Westergren
58 */
59public class DefaultDescriptorFieldTest /*extends TestCase*/ {
60 public static void main(String[] args) throws Exception {
61 boolean fail = false;
62 Object test = new DefaultDescriptorFieldTest("Test");
63 for (Method m : DefaultDescriptorFieldTest.class.getMethods()) {
64 if (m.getName().startsWith("test") &&
65 m.getParameterTypes().length == 0) {
66 System.out.println("Testing " + m.getName());
67 try {
68 m.invoke(test);
69 } catch (InvocationTargetException e) {
70 fail = true;
71 Throwable t = e.getCause();
72 System.out.println("FAILED: exception: " + t);
73 t.printStackTrace(System.out);
74 }
75 }
76 }
77 if (fail)
78 throw new Exception("TEST FAILED");
79 }
80
81 //No check WHICH constructor is reflected, at least when the classes tested are constructed,
82 //so I just use first one that came to mind.
83 final Constructor[] constArr = String.class.getConstructors();
84 final Constructor dummyConstructor = constArr[0];
85
86
87 Method getMethod = null;
88
89 /** Creates a new instance of MBeanTest */
90 public DefaultDescriptorFieldTest(final String name) {
91 try {
92 getMethod = String.class.getMethod("toString");
93 } catch (SecurityException ex) {
94 ex.printStackTrace();
95 } catch (NoSuchMethodException ex) {
96 ex.printStackTrace();
97 }
98 }
99
100 /**
101 * Test instantiating the 5 different classes with a null
102 * Descriptor, and also setting a null descriptor after.
103 * Expected: Default Descriptors created.
104 */
105 public void testNullDescriptors()
106 throws IntrospectionException, MBeanException {
107 final ModelMBeanConstructorInfo constInfo =
108 new ModelMBeanConstructorInfo("Dummy", dummyConstructor, null);
109 constInfo.setDescriptor(null);
110 ModelMBeanAttributeInfo attInfo =
111 new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, null);
112 attInfo.setDescriptor(null);
113 ModelMBeanNotificationInfo notInfo =
114 new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", null);
115 notInfo.setDescriptor(null);
116 ModelMBeanOperationInfo opInfo =
117 new ModelMBeanOperationInfo("test", getMethod, null);
118 opInfo.setDescriptor(null);
119 ModelMBeanInfoSupport infoSupport =
120 new ModelMBeanInfoSupport(new DummyModelMBeanInfo());
121 infoSupport.setDescriptor(null,null);
122 infoSupport.setDescriptor(null, "mbean");
123 }
124
125 /**
126 * Test instantiating and setting a Descriptor without the "name",
127 * "descriptorType" or "role" fields. This also tests whether the
128 * Descriptor is cloned before default values are set, since
129 * default values for one class will be incorrect for the next.
130 * Expected: Descriptor should be cloned, missing default values should be
131 * set
132 */
133 public void testFieldlessDescriptor()
134 throws IntrospectionException, MBeanException {
135 Descriptor theNamelessOne = new DescriptorSupport();
136 final ModelMBeanConstructorInfo constInfo =
137 new ModelMBeanConstructorInfo("Dummy", dummyConstructor, theNamelessOne);
138 constInfo.setDescriptor(theNamelessOne);
139 ModelMBeanAttributeInfo attInfo =
140 new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, theNamelessOne);
141 attInfo.setDescriptor(theNamelessOne);
142 ModelMBeanNotificationInfo notInfo =
143 new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", theNamelessOne);
144 notInfo.setDescriptor(theNamelessOne);
145 ModelMBeanOperationInfo opInfo =
146 new ModelMBeanOperationInfo("test", getMethod, theNamelessOne);
147 opInfo.setDescriptor(theNamelessOne);
148 ModelMBeanInfoSupport infoSupport = new ModelMBeanInfoSupport(new DummyModelMBeanInfo());
149 infoSupport.setDescriptor(theNamelessOne, null);
150 infoSupport.setDescriptor(theNamelessOne, "mbean");
151 }
152
153
154 /**
155 * Creates an empty DescriptorSupport and then test that ModelMBeanConstructorInfo accepts
156 * the correct fields in validation one by one.
157 */
158 public void testCorrectConstructorDescriptors()
159 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
160 Descriptor cDesc = new DescriptorSupport(new String[0],new String[0]);
161 final ModelMBeanConstructorInfo constInfo =
162 new ModelMBeanConstructorInfo("Dummy", dummyConstructor, cDesc);
163 assertFalse(fieldRefuted(constInfo, cDesc, "name" , "java.lang.String"));
164 assertFalse(fieldRefuted(constInfo, cDesc, "role" , "constructor"));
165 assertFalse(fieldRefuted(constInfo, cDesc, "descriptorType" , "operation"));
166 }
167
168 /**
169 * Test that ModelMBeanConstructorInfo refutes incorrect fields in validation one by one.
170 */
171 public void testIncorrectConstructorDescriptors()
172 throws NoSuchMethodException, IllegalAccessException {
173 Descriptor cDesc = new DescriptorSupport(
174 new String[] {"getMethod", "setMethod", "role", "Class", "name", "descriptorType"},
175 new String[] {"dummyGetMethod", "dummySetMethod", "constructor", "dummyClass", "java.lang.String", "operation"});
176 final ModelMBeanConstructorInfo constInfo = new ModelMBeanConstructorInfo("Dummy", dummyConstructor, cDesc);
177 assertTrue(fieldRefuted(constInfo, cDesc, "name" , "blah"));
178 assertTrue(fieldRefuted(constInfo, cDesc, "descriptorType", "mbean"));
179 assertTrue(fieldRefuted(constInfo, cDesc, "descriptorType", "notification"));
180 assertTrue(fieldRefuted(constInfo, cDesc, "descriptorType", "constructor"));
181 assertTrue(fieldRefuted(constInfo, cDesc, "role", "operation"));
182 }
183
184 public void testCorrectAttributeDescriptors()
185 throws IntrospectionException, NoSuchMethodException, IllegalAccessException {
186 Descriptor aDesc = new DescriptorSupport(new String[0],new String[0]);
187 final ModelMBeanAttributeInfo attInfo = new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, null);
188 assertFalse(fieldRefuted(attInfo, aDesc, "name" , "dummyAttInfoName"));
189 assertFalse(fieldRefuted(attInfo, aDesc, "descriptorType" , "attribute"));
190 }
191
192 public void testIncorrectAttributeDescriptors()
193 throws IntrospectionException, NoSuchMethodException, IllegalAccessException {
194 Descriptor aDesc = new DescriptorSupport();
195 final ModelMBeanAttributeInfo attInfo = new ModelMBeanAttributeInfo("dummyAttInfoName", "dummyAttInfoDesc", getMethod, null, null);
196 assertTrue(fieldRefuted(attInfo, aDesc, "name" , "blah"));
197 assertTrue(fieldRefuted(attInfo, aDesc, "descriptorType" , "constructor"));
198 assertTrue(fieldRefuted(attInfo, aDesc, "descriptorType" , "notification"));
199 }
200
201 public void testCorrectNotificationDescriptors()
202 throws NoSuchMethodException, IllegalAccessException {
203 Descriptor nDesc = new DescriptorSupport();
204 final ModelMBeanNotificationInfo nInfo = new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", nDesc);
205 assertFalse(fieldRefuted(nInfo, nDesc, "name" , "notificationClassName"));
206 assertFalse(fieldRefuted(nInfo, nDesc, "descriptorType" , "notification"));
207 }
208
209 public void testIncorrectNotificationDescriptors()
210 throws NoSuchMethodException, IllegalAccessException {
211 Descriptor nDesc = new DescriptorSupport();
212 final ModelMBeanNotificationInfo nInfo = new ModelMBeanNotificationInfo(null, "notificationClassName", "daName", nDesc);
213 assertTrue(fieldRefuted(nInfo, nDesc, "name" , "blah"));
214 assertTrue(fieldRefuted(nInfo, nDesc, "descriptorType" , "constructor"));
215 assertTrue(fieldRefuted(nInfo, nDesc, "descriptorType" , "operation"));
216 }
217
218 public void testCorrectOperationDescriptors()
219 throws NoSuchMethodException, IllegalAccessException {
220 Descriptor opDesc = new DescriptorSupport();
221 final ModelMBeanOperationInfo opInfo = new ModelMBeanOperationInfo("test", "readable description", null, "type", 1, opDesc);
222 assertFalse(fieldRefuted(opInfo, opDesc, "name" , "test"));
223 assertFalse(fieldRefuted(opInfo, opDesc, "descriptorType" , "operation"));
224 assertFalse(fieldRefuted(opInfo, opDesc, "role" , "operation"));
225 assertFalse(fieldRefuted(opInfo, opDesc, "role" , "getter"));
226 assertFalse(fieldRefuted(opInfo, opDesc, "role" , "setter"));
227 }
228
229 public void testIncorrectOperationDescriptors()
230 throws NoSuchMethodException, IllegalAccessException {
231 Descriptor opDesc = new DescriptorSupport();
232 final ModelMBeanOperationInfo opInfo = new ModelMBeanOperationInfo("test", "readable description", null, "type", 1, opDesc);
233 assertTrue(fieldRefuted(opInfo, opDesc, "name" , "DENIED!!"));
234 assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "constructor"));
235 assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "attribute"));
236 assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "notification"));
237 assertTrue(fieldRefuted(opInfo, opDesc, "descriptorType" , "x"));
238 }
239
240 //TODO also test ModelMBeanInfoSupport perhaps. Slightly more difficult to set up and test.
241
242 /**
243 * Clones descriptor, sets a new value in the clone and tries to apply clone to
244 * reflected Model*Info object method. The new field should be refuted if it
245 * is a bad value.
246 */
247 //I like java, but this is one case where duck typing would have been slightly easier I think. :)
248 private boolean fieldRefuted(Object mbeanInfo, Descriptor desc, String fieldName, String newValue)
249 throws NoSuchMethodException, IllegalAccessException {
250 Method setDescMethod = mbeanInfo.getClass().getMethod("setDescriptor", Descriptor.class);
251 Descriptor newDesc = (Descriptor)desc.clone();
252 boolean refused = false;
253 newDesc.setField(fieldName, newValue);
254 try {
255 setDescMethod.invoke(mbeanInfo, newDesc);
256 } catch (InvocationTargetException ex) {
257 //If we get classcast exception, someone passed in a bad object to reflection.
258 //Perhaps an unnecessary check, this cast?
259 RuntimeOperationsException rex = (RuntimeOperationsException)ex.getTargetException();
260 refused = true;
261 }
262 return refused;
263 }
264
265 /**
266 * Dummy class used to create test objects. May not be needed.
267 */
268 private class DummyModelMBeanInfo implements ModelMBeanInfo {
269 public Descriptor[] getDescriptors(String inDescriptorType)
270 throws MBeanException, RuntimeOperationsException {
271 return null;
272 }
273
274 public void setDescriptors(Descriptor[] inDescriptors)
275 throws MBeanException, RuntimeOperationsException {
276
277 }
278
279 public Descriptor getDescriptor(String inDescriptorName, String inDescriptorType)
280 throws MBeanException, RuntimeOperationsException {
281 return null;
282 }
283
284 public void setDescriptor(Descriptor inDescriptor, String inDescriptorType)
285 throws MBeanException, RuntimeOperationsException {
286
287 }
288
289 public Descriptor getMBeanDescriptor()
290 throws MBeanException, RuntimeOperationsException {
291 return null;
292 }
293
294 public void setMBeanDescriptor(Descriptor inDescriptor)
295 throws MBeanException, RuntimeOperationsException {
296
297 }
298
299 public ModelMBeanAttributeInfo getAttribute(String inName)
300 throws MBeanException, RuntimeOperationsException {
301 return null;
302 }
303
304 public ModelMBeanOperationInfo getOperation(String inName)
305 throws MBeanException, RuntimeOperationsException {
306 return null;
307 }
308
309 public ModelMBeanNotificationInfo getNotification(String inName)
310 throws MBeanException, RuntimeOperationsException {
311 return null;
312 }
313
314 public MBeanAttributeInfo[] getAttributes() {
315 return null;
316 }
317
318 public String getClassName() {
319 return "AnonMBeanInfoImpl";
320 }
321
322 public MBeanConstructorInfo[] getConstructors() {
323 return null;
324 }
325
326 public String getDescription() {
327 return null;
328 }
329
330 public MBeanNotificationInfo[] getNotifications() {
331 return null;
332 }
333
334 public MBeanOperationInfo[] getOperations() {
335 return null;
336 }
337
338 public Object clone() {
339 return null;
340
341 }
342
343 }
344
345 private static void assertFalse(boolean x) {
346 assertTrue(!x);
347 }
348
349 private static void assertTrue(boolean x) {
350 if (!x)
351 throw new AssertionError("Assertion failed");
352 }
353
354}