    1   /***
    2    *
    3    * Copyright 2004 Hiram Chirino
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    * http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   **/
    18  package org.codehaus.activemq.filter;
    19
    20  import junit.framework.TestCase;
    21  import org.codehaus.activemq.filter.MultiExpressionEvaluator.ExpressionListener;
    22  import org.codehaus.activemq.message.ActiveMQMessage;
    23  import org.codehaus.activemq.selector.SelectorParser;
    24
    25  import javax.jms.JMSException;
    26  import javax.jms.Message;
    27  import java.util.ArrayList;
    28  import java.util.Iterator;
    29
    30  /***
    31   * Test cases for the MultiExpressionEvaluator class.
    32   */
    33  public class MultiExpressionEvaluatorTest extends TestCase {
    34      MultiExpressionEvaluator evaluator = new MultiExpressionEvaluator();
    35      ArrayList expressions = new ArrayList();
    36
    37      /***
    38       * @see junit.framework.TestCase#setUp()
    39       */
    40      protected void setUp() throws Exception {
    41          // Add a few expressions that have matching nested expressions.
    42          // Make sure that there are 3 more true expressions than false ones.
    43          expressions.add(parseTrue("(3+4=7 AND 3+4=7) OR 1=10"));// true
    44          expressions.add(parseTrue("(3+4=7 AND 3+4=7) AND 3+4=7"));// true
    45          expressions.add(parseTrue("(3+4)*10=70"));// true
    46
    47          expressions.add(parseTrue("((3+4=7 AND 3+4=7) OR 1=10) AND 10 BETWEEN 0 AND 100"));// true
    48          expressions.add(parseFalse("(3+4)*5=70"));// false
    49
    50          expressions.add(parseTrue("10 BETWEEN 0 AND 100"));// true
    51          expressions.add(parseFalse("((3+4=7 OR 3+4=7) OR 1=10) AND 1=10"));// false
    52      }
    53
    54      /***
    55       * @param string
    56       * @return
    57       */
    58      private Expression parseTrue(String string) throws Exception {
    59          Expression rc = parse(string);
    60          assertEquals(rc.evaluate(new ActiveMQMessage()), Boolean.TRUE);
    61          return rc;
    62      }
    63
    64      /***
    65       * @param string
    66       * @return
    67       */
    68      private Expression parseFalse(String string) throws Exception {
    69          Expression rc = parse(string);
    70          assertEquals(rc.evaluate(new ActiveMQMessage()), Boolean.FALSE);
    71          return rc;
    72      }
    73
    74      protected Expression parse(String text) throws Exception {
    75          ExpressionFilter filter = (ExpressionFilter) new SelectorParser()
    76                  .parse(text);
    77          return filter.getExpression();
    78      }
    79
    80      /***
    81       * There are 3 expression that are true in the expressions list.
    82       * test them all and see if the count is right.
    83       */
    84      public void testSimpleEvaluation() {
    85
    86          final int hits[] = new int[]{0};
    87          final boolean test[] = new boolean[]{true};
    88
    89          for (Iterator i = expressions.iterator(); i.hasNext();) {
    90              Expression expr = (Expression) i.next();
    91              evaluator.addExpressionListner(expr, new ExpressionListener() {
    92                  public void evaluateResultEvent(Expression selector,
    93                                                  Message message, Object result) {
    94                      if (result.equals(Boolean.TRUE)) {
    95                          hits[0]++;
    96                      }
    97                      else {
    98                          hits[0]--;
    99                      }
    100                 }
    101             });
    102         }
    103
    104         evaluator.evaluate(new ActiveMQMessage());
    105         assertTrue(hits[0] == 3);
    106     }
    107
    108     static final public int SPEED_TEST_ITERATIONS = 100000;
    109
    110     public void testSpeedUsingMultiExpressionEvaluator() {
    111         // setup
    112         // Add all the expressions to the MultiExpressionEvaluator
    113         for (Iterator i = expressions.iterator(); i.hasNext();) {
    114             Expression expr = (Expression) i.next();
    115             evaluator.addExpressionListner(expr, new ExpressionListener() {
    116                 public void evaluateResultEvent(Expression selector, Message message, Object result) {
    117                 }
    118             });
    119         }
    120         ActiveMQMessage message = new ActiveMQMessage();
    121
    122         // Now evaluate:
    123         long start = System.currentTimeMillis();
    124         for (int i = 0; i < SPEED_TEST_ITERATIONS; i++) {
    125             evaluator.evaluate(message);
    126         }
    127         long end = System.currentTimeMillis();
    128         printSpeedReport("Using MultiExpressionEvaluator", start, end);
    129     }
    130
    131     public void testSpeedNotUsingMultiExpressionEvaluator() {
    132
    133         // setup
    134         Expression expr[] = new Expression[expressions.size()];
    135         expressions.toArray(expr);
    136         ActiveMQMessage message = new ActiveMQMessage();
    137
    138         // Now evaluate:
    139         long start = System.currentTimeMillis();
    140         for (int i = 0; i < SPEED_TEST_ITERATIONS; i++) {
    141
    142             for (int j = 0; j < expr.length; j++) {
    143                 try {
    144                     expr[j].evaluate(message);
    145                 }
    146                 catch (JMSException e) {
    147                 }
    148             }
    149         }
    150
    151         long end = System.currentTimeMillis();
    152         printSpeedReport("Not Using MultiExpressionEvaluator", start, end);
    153     }
    154
    155     /***
    156      * @param string
    157      * @param start
    158      * @param end
    159      */
    160     private void printSpeedReport(String testName, long start, long end) {
    161         System.out.println("Duration: " + testName + ": " + ((float) (end - start) / 1000.0) + " seconds.");
    162         System.out.println("Evaluation Rate: " + testName + ": " + ((float) (SPEED_TEST_ITERATIONS * expressions.size()) / (float) (end - start)) + " evaluations/second.");
    163     }
    164 }