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