jdk/test/javax/management/query/QueryParseTest.java
changeset 4156 acaa49a2768a
parent 4155 460e37d40f12
child 4159 9e3aae7675f1
equal deleted inserted replaced
4155:460e37d40f12 4156:acaa49a2768a
     1 /*
       
     2  * Copyright 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 QueryParseTest
       
    26  * @bug 6602310 6604768
       
    27  * @summary Test Query.fromString and Query.toString.
       
    28  * @author Eamonn McManus
       
    29  */
       
    30 
       
    31 import java.util.Collections;
       
    32 import java.util.Set;
       
    33 import javax.management.Attribute;
       
    34 import javax.management.AttributeList;
       
    35 import javax.management.AttributeNotFoundException;
       
    36 import javax.management.DynamicMBean;
       
    37 import javax.management.MBeanAttributeInfo;
       
    38 import javax.management.MBeanInfo;
       
    39 import javax.management.MBeanServer;
       
    40 import javax.management.MBeanServerDelegate;
       
    41 import javax.management.MBeanServerFactory;
       
    42 import javax.management.ObjectName;
       
    43 import javax.management.Query;
       
    44 import javax.management.QueryExp;
       
    45 
       
    46 public class QueryParseTest {
       
    47     // In this table, each string constant corresponds to a test case.
       
    48     // The objects following the string up to the next string are MBeans.
       
    49     // Each MBean must implement ExpectedValue to return true or false
       
    50     // according as it should return that value for the query parsed
       
    51     // from the given string.  The test will parse the string into a
       
    52     // a query and verify that the MBeans return the expected value
       
    53     // for that query.  Then it will convert the query back into a string
       
    54     // and into a second query, and check that the MBeans return the
       
    55     // expected value for that query too.  The reason we need to do all
       
    56     // this is that the spec talks about "equivalent queries", and gives
       
    57     // the implementation wide scope to rearrange queries.  So we cannot
       
    58     // just compare string values.
       
    59     //
       
    60     // We could also write an implementation-dependent test that knew what
       
    61     // the strings look like, and that would have to be changed if the
       
    62     // implementation changed.  But the approach here is cleaner.
       
    63     //
       
    64     // To simplify the creation of MBeans, most use the expectTrue or
       
    65     // expectFalse methods.  The parameters of these methods end up in
       
    66     // attributes called "A", "B", "C", etc.
       
    67     private static final Object[] queryTests = {
       
    68         // RELATIONS
       
    69 
       
    70         "A < B",
       
    71         expectTrue(1, 2), expectTrue(1.0, 2.0), expectTrue("one", "two"),
       
    72         expectTrue(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY),
       
    73         expectFalse(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY),
       
    74         expectFalse(1, 1), expectFalse(1.0, 1.0), expectFalse("one", "one"),
       
    75         expectFalse(2, 1), expectFalse(2.0, 1.0), expectFalse("two", "one"),
       
    76         expectFalse(Double.NaN, Double.NaN),
       
    77 
       
    78         "One = two",
       
    79         expectTrueOneTwo(1, 1), expectTrueOneTwo(1.0, 1.0),
       
    80         expectFalseOneTwo(1, 2), expectFalseOneTwo(2, 1),
       
    81 
       
    82         "A <= B",
       
    83         expectTrue(1, 1), expectTrue(1, 2), expectTrue("one", "one"),
       
    84         expectTrue("one", "two"),
       
    85         expectFalse(2, 1), expectFalse("two", "one"),
       
    86         expectFalse(Double.NaN, Double.NaN),
       
    87 
       
    88         "A >= B",
       
    89         expectTrue(1, 1), expectTrue(2, 1), expectTrue("two", "one"),
       
    90         expectFalse(1, 2), expectFalse("one", "two"),
       
    91 
       
    92         "A > B",
       
    93         expectTrue(2, 1), expectTrue("two", "one"),
       
    94         expectFalse(2, 2), expectFalse(1, 2), expectFalse(1.0, 2.0),
       
    95         expectFalse("one", "two"),
       
    96 
       
    97         "A <> B",
       
    98         expectTrue(1, 2), expectTrue("foo", "bar"),
       
    99         expectFalse(1, 1), expectFalse("foo", "foo"),
       
   100 
       
   101         "A != B",
       
   102         expectTrue(1, 2), expectTrue("foo", "bar"),
       
   103         expectFalse(1, 1), expectFalse("foo", "foo"),
       
   104 
       
   105         // PARENTHESES
       
   106 
       
   107         "(((A))) = (B)",
       
   108         expectTrue(1, 1), expectFalse(1, 2),
       
   109 
       
   110         "(A = B)",
       
   111         expectTrue(1, 1), expectFalse(1, 2),
       
   112 
       
   113         "(((A = (B))))",
       
   114         expectTrue(1, 1), expectFalse(1, 2),
       
   115 
       
   116         // INTEGER LITERALS
       
   117 
       
   118         "A = 1234567890123456789",
       
   119         expectTrue(1234567890123456789L), expectFalse(123456789L),
       
   120 
       
   121         "A = +1234567890123456789",
       
   122         expectTrue(1234567890123456789L), expectFalse(123456789L),
       
   123 
       
   124         "A = -1234567890123456789",
       
   125         expectTrue(-1234567890123456789L), expectFalse(-123456789L),
       
   126 
       
   127 
       
   128         "A = + 1234567890123456789",
       
   129         expectTrue(1234567890123456789L), expectFalse(123456789L),
       
   130 
       
   131         "A = - 1234567890123456789",
       
   132         expectTrue(-1234567890123456789L), expectFalse(-123456789L),
       
   133 
       
   134         "A = " + Long.MAX_VALUE,
       
   135         expectTrue(Long.MAX_VALUE), expectFalse(Long.MIN_VALUE),
       
   136 
       
   137         "A = " + Long.MIN_VALUE,
       
   138         expectTrue(Long.MIN_VALUE), expectFalse(Long.MAX_VALUE),
       
   139 
       
   140         // DOUBLE LITERALS
       
   141 
       
   142         "A = 0.0",
       
   143         expectTrue(0.0), expectFalse(1.0),
       
   144 
       
   145         "A = 0.0e23",
       
   146         expectTrue(0.0), expectFalse(1.0),
       
   147 
       
   148         "A = 1.2e3",
       
   149         expectTrue(1.2e3), expectFalse(1.2),
       
   150 
       
   151         "A = +1.2",
       
   152         expectTrue(1.2), expectFalse(-1.2),
       
   153 
       
   154         "A = 1.2e+3",
       
   155         expectTrue(1.2e3), expectFalse(1.2),
       
   156 
       
   157         "A = 1.2e-3",
       
   158         expectTrue(1.2e-3), expectFalse(1.2),
       
   159 
       
   160         "A = 1.2E3",
       
   161         expectTrue(1.2e3), expectFalse(1.2),
       
   162 
       
   163         "A = -1.2e3",
       
   164         expectTrue(-1.2e3), expectFalse(1.2),
       
   165 
       
   166         "A = " + Double.MAX_VALUE,
       
   167         expectTrue(Double.MAX_VALUE), expectFalse(Double.MIN_VALUE),
       
   168 
       
   169         "A = " + -Double.MAX_VALUE,
       
   170         expectTrue(-Double.MAX_VALUE), expectFalse(-Double.MIN_VALUE),
       
   171 
       
   172         "A = " + Double.MIN_VALUE,
       
   173         expectTrue(Double.MIN_VALUE), expectFalse(Double.MAX_VALUE),
       
   174 
       
   175         "A = " + -Double.MIN_VALUE,
       
   176         expectTrue(-Double.MIN_VALUE), expectFalse(-Double.MAX_VALUE),
       
   177 
       
   178         Query.toString(  // A = Infinity   ->   A = (1.0/0.0)
       
   179                 Query.eq(Query.attr("A"), Query.value(Double.POSITIVE_INFINITY))),
       
   180         expectTrue(Double.POSITIVE_INFINITY),
       
   181         expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
       
   182 
       
   183         Query.toString(  // A = -Infinity   ->   A = (-1.0/0.0)
       
   184                 Query.eq(Query.attr("A"), Query.value(Double.NEGATIVE_INFINITY))),
       
   185         expectTrue(Double.NEGATIVE_INFINITY),
       
   186         expectFalse(0.0), expectFalse(Double.POSITIVE_INFINITY),
       
   187 
       
   188         Query.toString(  // A < NaN   ->   A < (0.0/0.0)
       
   189                 Query.lt(Query.attr("A"), Query.value(Double.NaN))),
       
   190         expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
       
   191         expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN),
       
   192 
       
   193         Query.toString(  // A >= NaN   ->   A < (0.0/0.0)
       
   194                 Query.geq(Query.attr("A"), Query.value(Double.NaN))),
       
   195         expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY),
       
   196         expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN),
       
   197 
       
   198         // STRING LITERALS
       
   199 
       
   200         "A = 'blim'",
       
   201         expectTrue("blim"), expectFalse("blam"),
       
   202 
       
   203         "A = 'can''t'",
       
   204         expectTrue("can't"), expectFalse("cant"), expectFalse("can''t"),
       
   205 
       
   206         "A = '''blim'''",
       
   207         expectTrue("'blim'"), expectFalse("'blam'"),
       
   208 
       
   209         "A = ''",
       
   210         expectTrue(""), expectFalse((Object) null),
       
   211 
       
   212         // BOOLEAN LITERALS
       
   213 
       
   214         "A = true",
       
   215         expectTrue(true), expectFalse(false), expectFalse((Object) null),
       
   216 
       
   217         "A = TRUE",
       
   218         expectTrue(true), expectFalse(false),
       
   219 
       
   220         "A = TrUe",
       
   221         expectTrue(true), expectFalse(false),
       
   222 
       
   223         "A = false",
       
   224         expectTrue(false), expectFalse(true),
       
   225 
       
   226         "A = fAlSe",
       
   227         expectTrue(false), expectFalse(true),
       
   228 
       
   229         "A = \"true\"",   // An attribute called "true"
       
   230         expectFalse(true), expectFalse(false), expectFalse("\"true\""),
       
   231         newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.2}, true),
       
   232         newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.3}, false),
       
   233 
       
   234         "A = \"False\"",
       
   235         expectFalse(true), expectFalse(false), expectFalse("\"False\""),
       
   236         newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.2}, true),
       
   237         newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.3}, false),
       
   238 
       
   239         // ARITHMETIC
       
   240 
       
   241         "A + B = 10",
       
   242         expectTrue(4, 6), expectFalse(3, 8),
       
   243 
       
   244         "A + B = 'blim'",
       
   245         expectTrue("bl", "im"), expectFalse("bl", "am"),
       
   246 
       
   247         "A - B = 10",
       
   248         expectTrue(16, 6), expectFalse(16, 3),
       
   249 
       
   250         "A * B = 10",
       
   251         expectTrue(2, 5), expectFalse(3, 3),
       
   252 
       
   253         "A / B = 10",
       
   254         expectTrue(70, 7), expectTrue(70.0, 7), expectFalse(70.01, 7),
       
   255 
       
   256         "A + B + C = 10",
       
   257         expectTrue(2, 3, 5), expectFalse(2, 4, 8),
       
   258 
       
   259         "A+B+C=10",
       
   260         expectTrue(2, 3, 5), expectFalse(2, 4, 8),
       
   261 
       
   262         "A + B + C + D = 10",
       
   263         expectTrue(1, 2, 3, 4), expectFalse(2, 3, 4, 5),
       
   264 
       
   265         "A + (B + C) = 10",
       
   266         expectTrue(2, 3, 5), expectFalse(2, 4, 8),
       
   267 
       
   268         // It is not correct to rearrange A + (B + C) as A + B + C
       
   269         // (which means (A + B) + C), because of overflow.
       
   270         // In particular Query.toString must not do this.
       
   271         "A + (B + C) = " + Double.MAX_VALUE,  // ensure no false associativity
       
   272         expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE),
       
   273         expectFalse(-Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE),
       
   274 
       
   275         "A * (B * C) < " + Double.MAX_VALUE,  // same test for multiplication
       
   276         expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE),
       
   277         expectFalse(Double.MIN_VALUE, Double.MAX_VALUE, Double.MAX_VALUE),
       
   278 
       
   279         "A * B + C = 10",
       
   280         expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
       
   281 
       
   282         "A*B+C=10",
       
   283         expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
       
   284 
       
   285         "(A * B) + C = 10",
       
   286         expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3),
       
   287 
       
   288         "A + B * C = 10",
       
   289         expectTrue(1, 3, 3), expectTrue(2, 2, 4), expectFalse(1, 2, 3),
       
   290 
       
   291         "A - B * C = 10",
       
   292         expectTrue(16, 2, 3), expectFalse(15, 2, 2),
       
   293 
       
   294         "A + B / C = 10",
       
   295         expectTrue(5, 15, 3), expectFalse(5, 16, 4),
       
   296 
       
   297         "A - B / C = 10",
       
   298         expectTrue(16, 12, 2), expectFalse(15, 10, 3),
       
   299 
       
   300         "A * (B + C) = 10",
       
   301         expectTrue(2, 2, 3), expectFalse(1, 2, 3),
       
   302 
       
   303         "A / (B + C) = 10",
       
   304         expectTrue(70, 4, 3), expectFalse(70, 3, 5),
       
   305 
       
   306         "A * (B - C) = 10",
       
   307         expectTrue(2, 8, 3), expectFalse(2, 3, 8),
       
   308 
       
   309         "A / (B - C) = 10",
       
   310         expectTrue(70, 11, 4), expectFalse(70, 4, 11),
       
   311 
       
   312         "A / B / C = 10",
       
   313         expectTrue(140, 2, 7), expectFalse(100, 5, 5),
       
   314 
       
   315         "A / (B / C) = 10",
       
   316         expectTrue(70, 14, 2), expectFalse(70, 10, 7),
       
   317 
       
   318         // LOGIC
       
   319 
       
   320         "A = B or C = D",
       
   321         expectTrue(1, 1, 2, 3), expectTrue(1, 2, 3, 3), expectTrue(1, 1, 2, 2),
       
   322         expectFalse(1, 2, 3, 4), expectFalse("!", "!!", "?", "??"),
       
   323 
       
   324         "A = B and C = D",
       
   325         expectTrue(1, 1, 2, 2),
       
   326         expectFalse(1, 1, 2, 3), expectFalse(1, 2, 3, 3),
       
   327 
       
   328         "A = 1 and B = 2 and C = 3",
       
   329         expectTrue(1, 2, 3), expectFalse(1, 2, 4),
       
   330 
       
   331         "A = 1 or B = 2 or C = 3",
       
   332         expectTrue(1, 2, 3), expectTrue(1, 0, 0), expectTrue(0, 0, 3),
       
   333         expectFalse(2, 3, 4),
       
   334 
       
   335         // grouped as (a and b) or (c and d)
       
   336         "A = 1 AND B = 2 OR C = 3 AND D = 4",
       
   337         expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4),
       
   338         expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1),
       
   339 
       
   340         "(A = 1 AND B = 2) OR (C = 3 AND D = 4)",
       
   341         expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4),
       
   342         expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1),
       
   343 
       
   344         "(A = 1 or B = 2) AND (C = 3 or C = 4)",
       
   345         expectTrue(1, 1, 3, 3), expectTrue(2, 2, 4, 4), expectTrue(1, 2, 3, 4),
       
   346         expectFalse(1, 2, 1, 2), expectFalse(3, 4, 3, 4),
       
   347 
       
   348         // LIKE
       
   349 
       
   350         "A like 'b*m'",
       
   351         expectTrue("blim"), expectTrue("bm"),
       
   352         expectFalse(""), expectFalse("blimmo"), expectFalse("mmm"),
       
   353 
       
   354         "A not like 'b*m'",
       
   355         expectFalse("blim"), expectFalse("bm"),
       
   356         expectTrue(""), expectTrue("blimmo"), expectTrue("mmm"),
       
   357 
       
   358         "A like 'b?m'",
       
   359         expectTrue("bim"), expectFalse("blim"),
       
   360 
       
   361         "A like '*can''t*'",
       
   362         expectTrue("can't"),
       
   363         expectTrue("I'm sorry Dave, I'm afraid I can't do that"),
       
   364         expectFalse("cant"), expectFalse("can''t"),
       
   365 
       
   366         "A like '\\**\\*'",
       
   367         expectTrue("*blim*"), expectTrue("**"),
       
   368         expectFalse("blim"), expectFalse("*asdf"), expectFalse("asdf*"),
       
   369 
       
   370         "A LIKE '%*_?'",
       
   371         expectTrue("%blim_?"), expectTrue("%_?"), expectTrue("%blim_!"),
       
   372         expectFalse("blim"), expectFalse("blim_"),
       
   373         expectFalse("_%"), expectFalse("??"), expectFalse(""), expectFalse("?"),
       
   374 
       
   375         Query.toString(
       
   376                 Query.initialSubString(Query.attr("A"), Query.value("*?%_"))),
       
   377         expectTrue("*?%_tiddly"), expectTrue("*?%_"),
       
   378         expectFalse("?%_tiddly"), expectFalse("*!%_"), expectFalse("*??_"),
       
   379         expectFalse("*?%!"), expectFalse("*?%!tiddly"),
       
   380 
       
   381         Query.toString(
       
   382                 Query.finalSubString(Query.attr("A"), Query.value("*?%_"))),
       
   383         expectTrue("tiddly*?%_"), expectTrue("*?%_"),
       
   384         expectFalse("tiddly?%_"), expectFalse("*!%_"), expectFalse("*??_"),
       
   385         expectFalse("*?%!"), expectFalse("tiddly*?%!"),
       
   386 
       
   387         // BETWEEN
       
   388 
       
   389         "A between B and C",
       
   390         expectTrue(1, 1, 2), expectTrue(2, 1, 2), expectTrue(2, 1, 3),
       
   391         expectFalse(3, 1, 2), expectFalse(0, 1, 2), expectFalse(2, 3, 1),
       
   392         expectTrue(1.0, 0.0, 2.0), expectFalse(2.0, 0.0, 1.0),
       
   393         expectTrue(0.0, 0.0, 0.0), expectTrue(1.0, 0.0, 1.0),
       
   394         expectTrue(1.0, 0.0, Double.POSITIVE_INFINITY),
       
   395         expectFalse(1.0, Double.NEGATIVE_INFINITY, 0.0),
       
   396         expectFalse(false, false, true), expectFalse(true, false, true),
       
   397         expectTrue("jim", "fred", "sheila"), expectFalse("fred", "jim", "sheila"),
       
   398 
       
   399         "A between B and C and 1+2=3",
       
   400         expectTrue(2, 1, 3), expectFalse(2, 3, 1),
       
   401 
       
   402         "A not between B and C",
       
   403         expectTrue(1, 2, 3), expectFalse(2, 1, 3),
       
   404 
       
   405         // IN
       
   406 
       
   407         "A in (1, 2, 3)",
       
   408         expectTrue(1), expectTrue(2), expectTrue(3),
       
   409         expectFalse(0), expectFalse(4),
       
   410 
       
   411         "A in (1)",
       
   412         expectTrue(1), expectFalse(0),
       
   413 
       
   414         "A in (1.2, 3.4)",
       
   415         expectTrue(1.2), expectTrue(3.4), expectFalse(0.0),
       
   416 
       
   417         "A in ('foo', 'bar')",
       
   418         expectTrue("foo"), expectTrue("bar"), expectFalse("baz"),
       
   419 
       
   420         "A in ('foo', 'bar') and 'bl'+'im'='blim'",
       
   421         expectTrue("foo"), expectTrue("bar"), expectFalse("baz"),
       
   422 
       
   423         "A in (B, C, D)",  // requires fix for CR 6604768
       
   424         expectTrue(1, 1, 2, 3), expectFalse(1, 2, 3, 4),
       
   425 
       
   426         "A not in (B, C, D)",
       
   427         expectTrue(1, 2, 3, 4), expectFalse(1, 1, 2, 3),
       
   428 
       
   429         // QUOTING
       
   430 
       
   431         "\"LIKE\" = 1 and \"NOT\" = 2 and \"INSTANCEOF\" = 3 and " +
       
   432                 "\"TRUE\" = 4 and \"FALSE\" = 5",
       
   433         newTester(
       
   434                 new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"},
       
   435                 new Object[] {1, 2, 3, 4, 5},
       
   436                 true),
       
   437         newTester(
       
   438                 new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"},
       
   439                 new Object[] {5, 4, 3, 2, 1},
       
   440                 false),
       
   441 
       
   442         "\"\"\"woo\"\"\" = 5",
       
   443         newTester(new String[] {"\"woo\""}, new Object[] {5}, true),
       
   444         newTester(new String[] {"\"woo\""}, new Object[] {4}, false),
       
   445         expectFalse(),
       
   446 
       
   447         // INSTANCEOF
       
   448 
       
   449         "instanceof '" + Tester.class.getName() + "'",
       
   450         expectTrue(),
       
   451 
       
   452         "instanceof '" + String.class.getName() + "'",
       
   453         expectFalse(),
       
   454 
       
   455         // LIKE OBJECTNAME
       
   456 
       
   457         // The test MBean is registered as a:b=c
       
   458         "like 'a:b=c'", expectTrue(),
       
   459         "like 'a:*'", expectTrue(),
       
   460         "like '*:b=c'", expectTrue(),
       
   461         "like 'a:b=*'", expectTrue(),
       
   462         "like 'a:b=?'", expectTrue(),
       
   463         "like 'd:b=c'", expectFalse(),
       
   464         "like 'a:b=??*'", expectFalse(),
       
   465         "like 'a:b=\"can''t\"'", expectFalse(),
       
   466 
       
   467         // QUALIFIED ATTRIBUTE
       
   468 
       
   469         Tester.class.getName() + "#A = 5",
       
   470         expectTrue(5), expectFalse(4),
       
   471 
       
   472         Tester.class.getName() + " # A = 5",
       
   473         expectTrue(5), expectFalse(4),
       
   474 
       
   475         Tester.class.getSuperclass().getName() + "#A = 5",
       
   476         expectFalse(5),
       
   477 
       
   478         DynamicMBean.class.getName() + "#A = 5",
       
   479         expectFalse(5),
       
   480 
       
   481         Tester.class.getName() + "#A = 5",
       
   482         new Tester(new String[] {"A"}, new Object[] {5}, false) {},
       
   483         // note the little {} at the end which means this is a subclass
       
   484         // and therefore QualifiedAttributeValue should return false.
       
   485 
       
   486         MBeanServerDelegate.class.getName() + "#SpecificationName LIKE '*'",
       
   487         new Wrapped(new MBeanServerDelegate(), true),
       
   488         new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
       
   489 
       
   490         // DOTTED ATTRIBUTE
       
   491 
       
   492         "A.canonicalName = '" +
       
   493                 MBeanServerDelegate.DELEGATE_NAME.getCanonicalName() + "'",
       
   494         expectTrue(MBeanServerDelegate.DELEGATE_NAME),
       
   495         expectFalse(ObjectName.WILDCARD),
       
   496 
       
   497         "A.class.name = 'java.lang.String'",
       
   498         expectTrue("blim"), expectFalse(95), expectFalse((Object) null),
       
   499 
       
   500         "A.canonicalName like 'JMImpl*:*'",
       
   501         expectTrue(MBeanServerDelegate.DELEGATE_NAME),
       
   502         expectFalse(ObjectName.WILDCARD),
       
   503 
       
   504         "A.true = 'blim'",
       
   505         new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true),
       
   506         new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false),
       
   507 
       
   508         "\"A.true\" = 'blim'",
       
   509         new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true),
       
   510         new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false),
       
   511 
       
   512         MBeanServerDelegate.class.getName() +
       
   513                 "#SpecificationName.class.name = 'java.lang.String'",
       
   514         new Wrapped(new MBeanServerDelegate(), true),
       
   515         new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
       
   516 
       
   517         MBeanServerDelegate.class.getName() +
       
   518                 " # SpecificationName.class.name = 'java.lang.String'",
       
   519         new Wrapped(new MBeanServerDelegate(), true),
       
   520         new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false),
       
   521 
       
   522         // CLASS
       
   523 
       
   524         "class = '" + Tester.class.getName() + "'",
       
   525         expectTrue(),
       
   526         new Wrapped(new MBeanServerDelegate(), false),
       
   527 
       
   528         "Class = '" + Tester.class.getName() + "'",
       
   529         expectTrue(),
       
   530         new Wrapped(new MBeanServerDelegate(), false),
       
   531     };
       
   532 
       
   533     private static final String[] incorrectQueries = {
       
   534         "", " ", "25", "()", "(a = b", "a = b)", "a.3 = 5",
       
   535         "a = " + Long.MAX_VALUE + "0",
       
   536         "a = " + Double.MAX_VALUE + "0",
       
   537         "a = " + Double.MIN_VALUE + "0",
       
   538         "a = 12a5", "a = 12e5e5", "a = 12.23.34",
       
   539         "a = 'can't'", "a = 'unterminated", "a = 'asdf''",
       
   540         "a = \"oops", "a = \"oops\"\"",
       
   541         "a like 5", "true or false",
       
   542         "a ! b", "? = 3", "a = @", "a##b",
       
   543         "a between b , c", "a between and c",
       
   544         "a in b, c", "a in 23", "a in (2, 3", "a in (2, 3x)",
       
   545         "a like \"foo\"", "a like b", "a like 23",
       
   546         "like \"foo\"", "like b", "like 23", "like 'a:b'",
       
   547         "5 like 'a'", "'a' like '*'",
       
   548         "a not= b", "a not = b", "a not b", "a not b c",
       
   549         "a = +b", "a = +'b'", "a = +true", "a = -b", "a = -'b'",
       
   550         "a#5 = b", "a#'b' = c",
       
   551         "a instanceof b", "a instanceof 17", "a instanceof",
       
   552         // "a like 'oops\\'", "a like '[oops'",
       
   553         // We don't check the above because Query.match doesn't.  If LIKE
       
   554         // rejected bad patterns then there would be some QueryExp values
       
   555         // that could not be converted to a string and back.
       
   556 
       
   557         // Check that -Long.MIN_VALUE is an illegal constant.  This is one more
       
   558         // than Long.MAX_VALUE and, like the Java language, we only allow it
       
   559         // if it is the operand of unary minus.
       
   560         "a = " + Long.toString(Long.MIN_VALUE).substring(1),
       
   561     };
       
   562 
       
   563     public static void main(String[] args) throws Exception {
       
   564         int nexti;
       
   565         String failed = null;
       
   566 
       
   567         System.out.println("TESTING CORRECT QUERY STRINGS");
       
   568         for (int i = 0; i < queryTests.length; i = nexti) {
       
   569             for (nexti = i + 1; nexti < queryTests.length; nexti++) {
       
   570                 if (queryTests[nexti] instanceof String)
       
   571                     break;
       
   572             }
       
   573             if (!(queryTests[i] instanceof String))
       
   574                 throw new Exception("Test bug: should be string: " + queryTests[i]);
       
   575 
       
   576             String qs = (String) queryTests[i];
       
   577             System.out.println("Test: " + qs);
       
   578 
       
   579             QueryExp qe = Query.fromString(qs);
       
   580             String qes = Query.toString(qe);
       
   581             System.out.println("...parses to: " + qes);
       
   582             final QueryExp[] queries;
       
   583             if (qes.equals(qs))
       
   584                 queries = new QueryExp[] {qe};
       
   585             else {
       
   586                 QueryExp qe2 = Query.fromString(qes);
       
   587                 String qes2 = Query.toString(qe2);
       
   588                 System.out.println("...which parses to: " + qes2);
       
   589                 if (qes.equals(qes2))
       
   590                     queries = new QueryExp[] {qe};
       
   591                 else
       
   592                     queries = new QueryExp[] {qe, qe2};
       
   593             }
       
   594 
       
   595             for (int j = i + 1; j < nexti; j++) {
       
   596                 Object mbean;
       
   597                 if (queryTests[j] instanceof Wrapped)
       
   598                     mbean = ((Wrapped) queryTests[j]).mbean();
       
   599                 else
       
   600                     mbean = queryTests[j];
       
   601                 boolean expect = ((ExpectedValue) queryTests[j]).expectedValue();
       
   602                 for (QueryExp qet : queries) {
       
   603                     boolean actual = runQuery(qet, mbean);
       
   604                     boolean ok = (expect == actual);
       
   605                     System.out.println(
       
   606                             "..." + mbean + " -> " + actual +
       
   607                             (ok ? " (OK)" : " ####INCORRECT####"));
       
   608                     if (!ok)
       
   609                         failed = qs;
       
   610                 }
       
   611             }
       
   612         }
       
   613 
       
   614         System.out.println();
       
   615         System.out.println("TESTING INCORRECT QUERY STRINGS");
       
   616         for (String s : incorrectQueries) {
       
   617             try {
       
   618                 QueryExp qe = Query.fromString(s);
       
   619                 System.out.println("###DID NOT GET ERROR:### \"" + s + "\"");
       
   620                 failed = s;
       
   621             } catch (IllegalArgumentException e) {
       
   622                 String es = (e.getClass() == IllegalArgumentException.class) ?
       
   623                     e.getMessage() : e.toString();
       
   624                 System.out.println("OK: exception for \"" + s + "\": " + es);
       
   625             }
       
   626         }
       
   627 
       
   628         if (failed == null)
       
   629             System.out.println("TEST PASSED");
       
   630         else
       
   631             throw new Exception("TEST FAILED: Last failure: " + failed);
       
   632     }
       
   633 
       
   634     private static boolean runQuery(QueryExp qe, Object mbean)
       
   635     throws Exception {
       
   636         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
       
   637         ObjectName name = new ObjectName("a:b=c");
       
   638         mbs.registerMBean(mbean, name);
       
   639         Set<ObjectName> names = mbs.queryNames(new ObjectName("a:*"), qe);
       
   640         if (names.isEmpty())
       
   641             return false;
       
   642         if (names.equals(Collections.singleton(name)))
       
   643             return true;
       
   644         throw new Exception("Unexpected query result set: " + names);
       
   645     }
       
   646 
       
   647     private static interface ExpectedValue {
       
   648         public boolean expectedValue();
       
   649     }
       
   650 
       
   651     private static class Wrapped implements ExpectedValue {
       
   652         private final Object mbean;
       
   653         private final boolean expect;
       
   654 
       
   655         Wrapped(Object mbean, boolean expect) {
       
   656             this.mbean = mbean;
       
   657             this.expect = expect;
       
   658         }
       
   659 
       
   660         Object mbean() {
       
   661             return mbean;
       
   662         }
       
   663 
       
   664         public boolean expectedValue() {
       
   665             return expect;
       
   666         }
       
   667     }
       
   668 
       
   669     private static class Tester implements DynamicMBean, ExpectedValue {
       
   670         private final AttributeList attributes;
       
   671         private final boolean expectedValue;
       
   672 
       
   673         Tester(AttributeList attributes, boolean expectedValue) {
       
   674             this.attributes = attributes;
       
   675             this.expectedValue = expectedValue;
       
   676         }
       
   677 
       
   678         Tester(String[] names, Object[] values, boolean expectedValue) {
       
   679             this(makeAttributeList(names, values), expectedValue);
       
   680         }
       
   681 
       
   682         private static AttributeList makeAttributeList(
       
   683                 String[] names, Object[] values) {
       
   684             if (names.length != values.length)
       
   685                 throw new Error("Test bug: names and values different length");
       
   686             AttributeList list = new AttributeList();
       
   687             for (int i = 0; i < names.length; i++)
       
   688                 list.add(new Attribute(names[i], values[i]));
       
   689             return list;
       
   690         }
       
   691 
       
   692         public Object getAttribute(String attribute)
       
   693         throws AttributeNotFoundException {
       
   694             for (Attribute a : attributes.asList()) {
       
   695                 if (a.getName().equals(attribute))
       
   696                     return a.getValue();
       
   697             }
       
   698             throw new AttributeNotFoundException(attribute);
       
   699         }
       
   700 
       
   701         public void setAttribute(Attribute attribute) {
       
   702             throw new UnsupportedOperationException();
       
   703         }
       
   704 
       
   705         public AttributeList getAttributes(String[] attributes) {
       
   706             AttributeList list = new AttributeList();
       
   707             for (String attribute : attributes) {
       
   708                 try {
       
   709                     list.add(new Attribute(attribute, getAttribute(attribute)));
       
   710                 } catch (AttributeNotFoundException e) {
       
   711                     // OK: ignore, per semantics of getAttributes
       
   712                 }
       
   713             }
       
   714             return list;
       
   715         }
       
   716 
       
   717         public AttributeList setAttributes(AttributeList attributes) {
       
   718             throw new UnsupportedOperationException();
       
   719         }
       
   720 
       
   721         public Object invoke(String actionName, Object[] params, String[] signature) {
       
   722             throw new UnsupportedOperationException();
       
   723         }
       
   724 
       
   725         public MBeanInfo getMBeanInfo() {
       
   726             MBeanAttributeInfo mbais[] = new MBeanAttributeInfo[attributes.size()];
       
   727             for (int i = 0; i < mbais.length; i++) {
       
   728                 Attribute attr = attributes.asList().get(i);
       
   729                 String name = attr.getName();
       
   730                 Object value = attr.getValue();
       
   731                 String type =
       
   732                         ((value == null) ? new Object() : value).getClass().getName();
       
   733                 mbais[i] = new MBeanAttributeInfo(
       
   734                         name, type, name, true, false, false);
       
   735             }
       
   736             return new MBeanInfo(
       
   737                     getClass().getName(), "descr", mbais, null, null, null);
       
   738         }
       
   739 
       
   740         public boolean expectedValue() {
       
   741             return expectedValue;
       
   742         }
       
   743 
       
   744         @Override
       
   745         public String toString() {
       
   746             return attributes.toString();
       
   747         }
       
   748     }
       
   749 
       
   750     // Method rather than field, to avoid circular init dependencies
       
   751     private static String[] abcd() {
       
   752         return new String[] {"A", "B", "C", "D"};
       
   753     }
       
   754 
       
   755     private static String[] onetwo() {
       
   756         return new String[] {"One", "two"};
       
   757     }
       
   758 
       
   759     private static Object expectTrue(Object... attrs) {
       
   760         return newTester(abcd(), attrs, true);
       
   761     }
       
   762 
       
   763     private static Object expectFalse(Object... attrs) {
       
   764         return newTester(abcd(), attrs, false);
       
   765     }
       
   766 
       
   767     private static Object expectTrueOneTwo(Object... attrs) {
       
   768         return newTester(onetwo(), attrs, true);
       
   769     }
       
   770 
       
   771     private static Object expectFalseOneTwo(Object... attrs) {
       
   772         return newTester(onetwo(), attrs, false);
       
   773     }
       
   774 
       
   775     private static Object newTester(String[] names, Object[] attrs, boolean expect) {
       
   776         AttributeList list = new AttributeList();
       
   777         for (int i = 0; i < attrs.length; i++)
       
   778             list.add(new Attribute(names[i], attrs[i]));
       
   779         return new Tester(list, expect);
       
   780     }
       
   781 }