1 /* |
|
2 * Copyright 2003-2008 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 * @summary Test named MBeanServers. |
|
27 * @author Daniel Fuchs |
|
28 * @bug 6299231 |
|
29 * @run clean NamedMBeanServerTest |
|
30 * @run build NamedMBeanServerTest |
|
31 * @run main NamedMBeanServerTest |
|
32 */ |
|
33 |
|
34 import java.util.Arrays; |
|
35 import java.util.EnumSet; |
|
36 import java.util.HashMap; |
|
37 import java.util.HashSet; |
|
38 import java.util.LinkedHashMap; |
|
39 import java.util.List; |
|
40 import java.util.Map; |
|
41 import java.util.Set; |
|
42 import javax.management.MBeanServer; |
|
43 import javax.management.MBeanServerBuilder; |
|
44 import javax.management.MBeanServerDelegate; |
|
45 import javax.management.MBeanServerFactory; |
|
46 |
|
47 /** |
|
48 * This test can probably be leveraged in the JCK to test compatibilty |
|
49 * of MBeanServerFactory *Name* method implementation. |
|
50 * @author dfuchs |
|
51 */ |
|
52 public class NamedMBeanServerTest { |
|
53 |
|
54 /** |
|
55 * One enum value for each way of creating an MBeanServer through the |
|
56 * MBeanServerFactory |
|
57 */ |
|
58 public static enum Creator { |
|
59 newMBeanServer() { |
|
60 public MBeanServer create(String domain) { |
|
61 return MBeanServerFactory.newMBeanServer(domain); |
|
62 } |
|
63 public String test(MBeanServer server, String domain) { |
|
64 System.out.println(toString()+"("+domain+")"); |
|
65 return test(server, |
|
66 MBeanServerFactory.DEFAULT_MBEANSERVER_NAME, |
|
67 domain); |
|
68 } |
|
69 public MBeanServer[] servers(Config config) { |
|
70 return config.ndServers; |
|
71 } |
|
72 public String[] strings(Config config) { |
|
73 return domains(config); |
|
74 } |
|
75 public String[] domains(Config config) { |
|
76 return config.newDomains; |
|
77 } |
|
78 public String[] names(Config config) { |
|
79 return null; |
|
80 } |
|
81 }, |
|
82 createMBeanServer() { |
|
83 public MBeanServer create(String domain) { |
|
84 return MBeanServerFactory.createMBeanServer(domain); |
|
85 } |
|
86 public String test(MBeanServer server, String domain) { |
|
87 System.out.println(toString()+"("+domain+")"); |
|
88 return test(server,MBeanServerFactory.DEFAULT_MBEANSERVER_NAME, |
|
89 domain); |
|
90 } |
|
91 public MBeanServer[] servers(Config config) { |
|
92 return config.cdServers; |
|
93 } |
|
94 public String[] strings(Config config) { |
|
95 return domains(config); |
|
96 } |
|
97 public String[] domains(Config config) { |
|
98 return config.createDomains; |
|
99 } |
|
100 public String[] names(Config config) { |
|
101 return null; |
|
102 } |
|
103 }, |
|
104 newNamedMBeanServer() { |
|
105 public MBeanServer create(String name) { |
|
106 return MBeanServerFactory.newNamedMBeanServer(name,null); |
|
107 } |
|
108 public String test(MBeanServer server, String name) { |
|
109 System.out.println(toString()+"("+name+",null)"); |
|
110 return test(server,name,"DefaultDomain"); |
|
111 } |
|
112 public MBeanServer[] servers(Config config) { |
|
113 return config.nnServers; |
|
114 } |
|
115 public String[] strings(Config config) { |
|
116 return names(config); |
|
117 } |
|
118 public String[] domains(Config config) { |
|
119 return null; |
|
120 } |
|
121 public String[] names(Config config) { |
|
122 return config.newNames; |
|
123 } |
|
124 }, |
|
125 createNamedMBeanServer() { |
|
126 public MBeanServer create(String name) { |
|
127 return MBeanServerFactory.createNamedMBeanServer(name,null); |
|
128 } |
|
129 public String test(MBeanServer server, String name) { |
|
130 System.out.println(toString()+"("+name+",null)"); |
|
131 return test(server,name,"DefaultDomain"); |
|
132 } |
|
133 public MBeanServer[] servers(Config config) { |
|
134 return config.cnServers; |
|
135 } |
|
136 public String[] strings(Config config) { |
|
137 return names(config); |
|
138 } |
|
139 public String[] domains(Config config) { |
|
140 return null; |
|
141 } |
|
142 public String[] names(Config config) { |
|
143 return config.createNames; |
|
144 } |
|
145 }; |
|
146 |
|
147 // creates an MBeanServer using the specified input string. |
|
148 // either a domain, (for UNNAMED) or a mbeanServerName (for NAMED) |
|
149 public abstract MBeanServer create(String string); |
|
150 |
|
151 // test the created server against the string used as input to create |
|
152 // it. |
|
153 public abstract String test(MBeanServer server, String ref); |
|
154 |
|
155 public abstract MBeanServer[] servers(Config config); |
|
156 public abstract String[] strings(Config config); |
|
157 public abstract String[] names(Config config); |
|
158 public abstract String[] domains(Config config); |
|
159 |
|
160 public MBeanServer[] servers(Config config, String... refs) { |
|
161 final MBeanServer[] servers = servers(config); |
|
162 final String[] strings = strings(config); |
|
163 final MBeanServer[] res = new MBeanServer[refs.length]; |
|
164 for (int i=0;i<refs.length;i++) { |
|
165 for (int j=0;j<strings.length;j++) { |
|
166 if (strings[j].equals(refs[i])) |
|
167 res[i]=servers[j]; |
|
168 } |
|
169 if (res[i] == null) |
|
170 throw new IllegalArgumentException(refs[i]); |
|
171 } |
|
172 return res; |
|
173 } |
|
174 |
|
175 String test(MBeanServer server, String name, String domain) { |
|
176 // whether the MBeanServer was created throug a "create" method |
|
177 boolean registered = REFERENCED.contains(this); |
|
178 if (!server.getDefaultDomain().equals(domain)) { |
|
179 return "Unexpected default domain: " + |
|
180 server.getDefaultDomain() + ", should be: " + domain; |
|
181 } |
|
182 if (!MBeanServerFactory.getMBeanServerName(server). |
|
183 equals(name)) { |
|
184 return " Unexpected name: " + |
|
185 MBeanServerFactory.getMBeanServerName(server) + |
|
186 ", should be: " + name; |
|
187 } |
|
188 List<MBeanServer> found = |
|
189 MBeanServerFactory.findMBeanServerByName(name); |
|
190 if (!registered && found.contains(server)) |
|
191 return " Server "+name+" found by name - " + |
|
192 "but should not be registered"; |
|
193 if (!registered && |
|
194 !name.equals(MBeanServerFactory.DEFAULT_MBEANSERVER_NAME) && |
|
195 found.size()>0) |
|
196 return " Server "+name+" had too many matches: " + found.size(); |
|
197 if (registered && !found.contains(server)) |
|
198 return " Server "+name+" not found by name - " + |
|
199 "but is registered!"; |
|
200 if (registered && |
|
201 !name.equals(MBeanServerFactory.DEFAULT_MBEANSERVER_NAME) && |
|
202 !(found.size()==1)) |
|
203 return " Server "+name+" had too many matches: " + found.size(); |
|
204 return null; |
|
205 } |
|
206 |
|
207 public static final EnumSet<Creator> NAMED = |
|
208 EnumSet.of(createNamedMBeanServer, newNamedMBeanServer); |
|
209 public static final EnumSet<Creator> UNNAMED = |
|
210 EnumSet.complementOf(NAMED); |
|
211 public static final EnumSet<Creator> REFERENCED = |
|
212 EnumSet.of(createMBeanServer, createNamedMBeanServer); |
|
213 public static final EnumSet<Creator> UNREFERENCED = |
|
214 EnumSet.complementOf(REFERENCED); |
|
215 |
|
216 } |
|
217 |
|
218 public static class Config { |
|
219 final String[] newDomains; |
|
220 final String[] createDomains; |
|
221 final String[] newNames; |
|
222 final String[] createNames; |
|
223 final MBeanServer[] ndServers; |
|
224 final MBeanServer[] cdServers; |
|
225 final MBeanServer[] nnServers; |
|
226 final MBeanServer[] cnServers; |
|
227 final Map<String,Set<MBeanServer>> queries; |
|
228 Config(String[][] data) { |
|
229 this(data[0],data[1],data[2],data[3]); |
|
230 } |
|
231 Config(String[] nd, String[] cd, String[] nn, String[] cn) { |
|
232 this.newDomains=nd.clone(); |
|
233 this.createDomains=cd.clone(); |
|
234 this.newNames=nn.clone(); |
|
235 this.createNames=cn.clone(); |
|
236 ndServers = new MBeanServer[nd.length]; |
|
237 cdServers = new MBeanServer[cd.length]; |
|
238 nnServers = new MBeanServer[nn.length]; |
|
239 cnServers = new MBeanServer[cn.length]; |
|
240 queries = new HashMap<String,Set<MBeanServer>>(); |
|
241 init(); |
|
242 } |
|
243 private void init() { |
|
244 for (Creator c : Creator.values()) fill(c); |
|
245 addQuery(null,Creator.createMBeanServer.servers(this)); |
|
246 addQuery(null,Creator.createNamedMBeanServer.servers(this)); |
|
247 addQuery("?*",Creator.createMBeanServer.servers(this)); |
|
248 addQuery("?*",Creator.createNamedMBeanServer.servers(this)); |
|
249 addQuery("*",Creator.createMBeanServer.servers(this)); |
|
250 addQuery("*",Creator.createNamedMBeanServer.servers(this)); |
|
251 addQuery(MBeanServerFactory.DEFAULT_MBEANSERVER_NAME, |
|
252 Creator.createMBeanServer.servers(this)); |
|
253 } |
|
254 private void addQuery(String pattern, MBeanServer... servers) { |
|
255 final Set<MBeanServer> s = getQuery(pattern); |
|
256 s.addAll(Arrays.asList(servers)); |
|
257 } |
|
258 public Set<MBeanServer> getQuery(String pattern) { |
|
259 final Set<MBeanServer> s = queries.get(pattern); |
|
260 if (s != null) return s; |
|
261 queries.put(pattern,new HashSet<MBeanServer>()); |
|
262 return queries.get(pattern); |
|
263 } |
|
264 public Set<String> getPatterns() { |
|
265 return queries.keySet(); |
|
266 } |
|
267 private void fill(Creator creator) { |
|
268 fill(creator.servers(this),creator.strings(this),creator); |
|
269 } |
|
270 private void fill(MBeanServer[] dest, String[] src, Creator creator) { |
|
271 for(int i=0;i<src.length;i++) dest[i]=creator.create(src[i]); |
|
272 } |
|
273 |
|
274 } |
|
275 |
|
276 static String[] domains(String... str) { |
|
277 return str; |
|
278 } |
|
279 static String[] names(String... str) { |
|
280 return str; |
|
281 } |
|
282 final static Config test1 = new Config(domains("foo1","foo2","foo3"), |
|
283 domains("foobar1","foobar2","foobar3","foobar4"), |
|
284 names("bar1","bar2"), |
|
285 names("barfoo1","barfoo2","barfoo3","batfox1","catfog2","foofoo3")); |
|
286 static { |
|
287 test1.addQuery("b*",Creator.createNamedMBeanServer.servers(test1, |
|
288 "barfoo1","barfoo2","barfoo3","batfox1")); |
|
289 test1.addQuery("*arf*",Creator.createNamedMBeanServer.servers(test1, |
|
290 "barfoo1","barfoo2","barfoo3")); |
|
291 test1.addQuery("*a?f*",Creator.createNamedMBeanServer.servers(test1, |
|
292 "barfoo1","barfoo2","barfoo3","batfox1","catfog2")); |
|
293 test1.addQuery("",new MBeanServer[0]); |
|
294 test1.addQuery("-",new MBeanServer[0]); |
|
295 test1.addQuery("def*",Creator.createMBeanServer.servers(test1)); |
|
296 } |
|
297 |
|
298 public static void test(Config config) throws Exception { |
|
299 for (Creator c : Creator.values()) { |
|
300 final MBeanServer[] s = c.servers(config); |
|
301 final String[] ref = c.strings(config); |
|
302 for (int i=0;i<s.length;i++) { |
|
303 final String msg = c.test(s[i], ref[i]); |
|
304 if (msg != null) |
|
305 throw new Exception(String.valueOf(c)+"["+i+"]: "+msg); |
|
306 } |
|
307 } |
|
308 for (String pat : config.getPatterns()) { |
|
309 System.out.print("findMBeanServerByName(\""+pat+"\"): ["); |
|
310 final List<MBeanServer> found = |
|
311 MBeanServerFactory.findMBeanServerByName(pat); |
|
312 String sep=" "; |
|
313 for (MBeanServer m : found) { |
|
314 System.out.print(sep+MBeanServerFactory.getMBeanServerName(m)); |
|
315 sep=", "; |
|
316 } |
|
317 System.out.println(" ]"); |
|
318 final Set<MBeanServer> founds = new HashSet<MBeanServer>(); |
|
319 founds.addAll(found); |
|
320 if (!founds.equals(config.getQuery(pat))) { |
|
321 final String msg = |
|
322 "bad result for findMBeanServerByName(\""+ |
|
323 pat+"\"): expected "+config.getQuery(pat).size()+", "+ |
|
324 "got "+founds.size(); |
|
325 throw new Exception(msg); |
|
326 } |
|
327 } |
|
328 } |
|
329 |
|
330 public static void testexception(Creator c, String name, |
|
331 Class<? extends Exception> error) throws Exception { |
|
332 Exception failed = null; |
|
333 MBeanServer server = null; |
|
334 try { |
|
335 server = c.create(name); |
|
336 } catch (Exception x) { |
|
337 failed = x; |
|
338 } finally { |
|
339 if (Creator.REFERENCED.contains(c) && server!=null) { |
|
340 MBeanServerFactory.releaseMBeanServer(server); |
|
341 } |
|
342 } |
|
343 if (failed == null && error != null) { |
|
344 throw new Exception("Expected "+error.getName()+ |
|
345 " for "+c+"("+name+")"); |
|
346 } |
|
347 if (error != null && !error.isInstance(failed)) |
|
348 throw new Exception("Expected "+error.getName()+ |
|
349 " for "+c+"("+name+"), caught "+failed); |
|
350 System.out.println(""+c+"("+name+") PASSED: "+ |
|
351 (failed==null?"no exception":String.valueOf(failed))); |
|
352 } |
|
353 |
|
354 private static final Map<String,Class<? extends Exception>> failures = |
|
355 new LinkedHashMap<String,Class<? extends Exception>>(); |
|
356 private static final Map<String,Class<? extends Exception>> legacy = |
|
357 new LinkedHashMap<String,Class<? extends Exception>>(); |
|
358 private static final String[] illegalnames = { |
|
359 "", "-", ":", ";", "?", "*", "wom?bat", "ran:tan.plan", |
|
360 "rin;tin.tin", "tab*mow" |
|
361 |
|
362 }; |
|
363 private static final String[] legalnames = { |
|
364 "wombat", "top.tip", "ran.tan.plan", "rin.tin.tin!" |
|
365 }; |
|
366 private static final String[] nofailures = { |
|
367 MBeanServerFactory.DEFAULT_MBEANSERVER_NAME, "default", null |
|
368 }; |
|
369 static { |
|
370 for (String s:illegalnames) |
|
371 failures.put(s, IllegalArgumentException.class); |
|
372 for (String s:nofailures) |
|
373 failures.put(s, null); |
|
374 legacy.putAll(failures); |
|
375 for (String s:legalnames) |
|
376 legacy.put(s, UnsupportedOperationException.class); |
|
377 |
|
378 } |
|
379 |
|
380 public static void test2(Map<String,Class<? extends Exception>> config) |
|
381 throws Exception { |
|
382 for (Creator c:Creator.NAMED) { |
|
383 for (String s:config.keySet()) testexception(c, s, config.get(s)); |
|
384 } |
|
385 } |
|
386 |
|
387 public static class LegacyBuilder extends MBeanServerBuilder { |
|
388 |
|
389 @Override |
|
390 public MBeanServerDelegate newMBeanServerDelegate() { |
|
391 return new MBeanServerDelegate() { |
|
392 @Override |
|
393 public synchronized String getMBeanServerId() { |
|
394 return "gloups"; |
|
395 } |
|
396 }; |
|
397 } |
|
398 |
|
399 } |
|
400 public static class LegacyBuilder2 extends MBeanServerBuilder { |
|
401 |
|
402 @Override |
|
403 public MBeanServerDelegate newMBeanServerDelegate() { |
|
404 return new MBeanServerDelegate() { |
|
405 @Override |
|
406 public synchronized String getMBeanServerId() { |
|
407 return "c'est la vie..."; |
|
408 } |
|
409 @Override |
|
410 public synchronized void setMBeanServerName(String name) { |
|
411 } |
|
412 |
|
413 }; |
|
414 } |
|
415 |
|
416 } |
|
417 |
|
418 public static void test3(Map<String,Class<? extends Exception>> config, |
|
419 String builderClassName) |
|
420 throws Exception { |
|
421 final String builder = |
|
422 System.getProperty("javax.management.builder.initial"); |
|
423 System.setProperty("javax.management.builder.initial", |
|
424 builderClassName); |
|
425 try { |
|
426 test2(config); |
|
427 } finally { |
|
428 if (builder != null) |
|
429 System.setProperty("javax.management.builder.initial", builder); |
|
430 else |
|
431 System.clearProperty("javax.management.builder.initial"); |
|
432 } |
|
433 } |
|
434 |
|
435 public static void main(String[] args) throws Exception { |
|
436 test(test1); |
|
437 test2(failures); |
|
438 test3(legacy,LegacyBuilder.class.getName()); |
|
439 test3(legacy,LegacyBuilder2.class.getName()); |
|
440 } |
|
441 } |
|