metron-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ceste...@apache.org
Subject [1/2] incubator-metron git commit: METRON-624: Updated Comparison/Equality Evaluations in Stellar closes apache/incubator-metron#404
Date Fri, 13 Jan 2017 17:59:39 GMT
Repository: incubator-metron
Updated Branches:
  refs/heads/master 52aa58050 -> 56ff50c3d


http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/BaseStellarProcessorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/BaseStellarProcessorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/BaseStellarProcessorTest.java
new file mode 100644
index 0000000..00fd3f3
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/BaseStellarProcessorTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.stellar;
+
+import org.apache.metron.common.dsl.Context;
+import org.apache.metron.common.dsl.ParseException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.*;
+
+@SuppressWarnings("ALL")
+public class BaseStellarProcessorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  BaseStellarProcessor<Object> processor;
+
+  @Before
+  public void setUp() throws Exception {
+    processor = new BaseStellarProcessor<>(Object.class);
+  }
+
+  @Test
+  public void makeSureBasicValidationIsWorking() throws Exception {
+    {
+      assertTrue(processor.validate(""));
+      assertTrue(processor.validate(null));
+      assertTrue(processor.validate("'ah'"));
+      assertTrue(processor.validate("true"));
+      assertTrue(processor.validate("1"));
+      assertTrue(processor.validate("1L"));
+      assertTrue(processor.validate("1F"));
+      assertTrue(processor.validate("1 < 2 // always true"));
+      assertTrue(processor.validate("1 < foo"));
+      assertTrue(processor.validate("(1 < foo)"));
+      assertTrue(processor.validate("foo < bar"));
+      assertTrue(processor.validate("foo < TO_FLOAT(bar)", false, Context.EMPTY_CONTEXT()));
+      assertTrue(processor.validate("if true then b else c"));
+      assertTrue(processor.validate("IF false THEN b ELSE c"));
+    }
+
+    {
+      assertFalse(processor.validate("'", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("(", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("()", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("'foo", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("foo << foo", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("1-1", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("1 -1", false, Context.EMPTY_CONTEXT()));
+      assertFalse(processor.validate("If a then b else c", false, Context.EMPTY_CONTEXT()));
+    }
+  }
+
+  @Test
+  public void validateShouldProperlyThrowExceptionOnInvalidStellarExpression() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unable to parse ': ");
+
+    processor.validate("'", true, Context.EMPTY_CONTEXT());
+  }
+
+  @Test
+  public void validateShouldProperlyThrowExceptionByDefaultOnInvalidStellarExpression() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unable to parse ': ");
+
+    processor.validate("'", Context.EMPTY_CONTEXT());
+  }
+
+  @Test
+  public void validateShouldProperlyThrowExceptionByDefaultOnInvalidStellarExpression2() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unable to parse ': ");
+
+    processor.validate("'");
+  }
+
+  @Test
+  public void validateMethodShouldFailOnUnknownFunctions() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage(" Unable to resolve function named 'UNKNOWN_FUNCTION'.");
+
+    assertTrue(processor.validate("1 < UNKNOWN_FUNCTION(3)", Context.EMPTY_CONTEXT()));
+  }
+
+  @Test
+  public void validateMethodShouldNotFailOnUnknownvariables() throws Exception {
+    assertTrue(processor.validate("unknown_variable\n\n"));
+    assertTrue(processor.validate("unknown_variable > 2", Context.EMPTY_CONTEXT()));
+  }
+
+  @Test
+  public void makeSureBasicLexerErrorsAreCaughtDuringValidation() throws Exception {
+    assertFalse(processor.validate("true †", false, Context.EMPTY_CONTEXT()));
+    assertFalse(processor.validate("¢ (1 + 2)", false, Context.EMPTY_CONTEXT()));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
index 60fdc13..e33a22b 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarArithmeticTest.java
@@ -307,4 +307,26 @@ public class StellarArithmeticTest {
     exception.expect(ParseException.class);
     run("--000000L", ImmutableMap.of());
   }
+
+  @Test(expected = ParseException.class)
+  public void unableToDivideByZeroWithIntegers() throws Exception {
+    run("0/0", ImmutableMap.of());
+  }
+
+  @Test(expected = ParseException.class)
+  public void unableToDivideByZeroWithLongs() throws Exception {
+    run("0L/0L", ImmutableMap.of());
+  }
+
+  @Test
+  public void ableToDivideByZero() throws Exception {
+    assertEquals(0F/0F, run("0F/0F", ImmutableMap.of()));
+    assertEquals(0D/0D, run("0D/0D", ImmutableMap.of()));
+    assertEquals(0D/0F, run("0D/0F", ImmutableMap.of()));
+    assertEquals(0F/0D, run("0F/0D", ImmutableMap.of()));
+    assertEquals(0F/0, run("0F/0", ImmutableMap.of()));
+    assertEquals(0D/0, run("0D/0", ImmutableMap.of()));
+    assertEquals(0/0D, run("0/0D", ImmutableMap.of()));
+    assertEquals(0/0F, run("0/0F", ImmutableMap.of()));
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
index 73a44b5..ab63d06 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarComparisonExpressionWithOperatorTest.java
@@ -19,16 +19,21 @@
 package org.apache.metron.common.stellar;
 
 import com.google.common.collect.ImmutableMap;
+import org.apache.metron.common.dsl.ParseException;
 import org.junit.Test;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import static org.apache.metron.common.utils.StellarProcessorUtils.run;
 import static org.apache.metron.common.utils.StellarProcessorUtils.runPredicate;
-import static org.junit.Assert.*;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
+@SuppressWarnings("ALL")
 public class StellarComparisonExpressionWithOperatorTest {
   @SuppressWarnings({"RedundantConditionalExpression", "ConstantConditions"})
   @Test
@@ -44,9 +49,12 @@ public class StellarComparisonExpressionWithOperatorTest {
     assertEquals(1L < 3.0f, run("1L < 3.0f", ImmutableMap.of()));
     assertEquals(1 < 3.0f, run("1 < 3.0f", ImmutableMap.of()));
     assertEquals(1.0 < 3.0f, run("1.0 < 3.0f", ImmutableMap.of()));
+    assertEquals(false, run("foo < 3.0f", ImmutableMap.of()));
+    assertEquals(false, run("foo < foo", ImmutableMap.of()));
     assertEquals(1L < 3.0f ? true : false, run("if 1L < 3.0f then true else false", ImmutableMap.of()));
   }
 
+  @SuppressWarnings("ConstantConditions")
   @Test
   public void checkComparisonOperationsWithFunctions() throws Exception {
     assertEquals(1f >= 2, run("TO_FLOAT(1) >= 2", ImmutableMap.of()));
@@ -76,4 +84,210 @@ public class StellarComparisonExpressionWithOperatorTest {
     assertTrue(runPredicate("", variableMap::get));
     assertTrue(runPredicate(" ", variableMap::get));
   }
+
+  @Test
+  public void compareNumberAndStringWithSameValueShouldBeFalse() throws Exception {
+    assertFalse(runPredicate("1 == '1'", new HashMap<>()::get));
+    assertFalse(runPredicate("'1' == 1", new HashMap<>()::get));
+  }
+
+  @Test
+  public void comparingNullShouldNotCauseNullPointer() throws Exception {
+    assertFalse(runPredicate("null == '1'", new HashMap<>()::get));
+    assertFalse(runPredicate("\"1\" == null", new HashMap<>()::get));
+    assertTrue(runPredicate("null == null", new HashMap<>()::get));
+  }
+
+  @Test
+  public void makeSureSingleQuotesAndDoubleQuotesAreEqual() throws Exception {
+    assertTrue(runPredicate("\"1\" == '1'", new HashMap<>()::get));
+    assertTrue(runPredicate("'1' == \"1\"", new HashMap<>()::get));
+    assertTrue(runPredicate("'1' == \"1\"", new HashMap<>()::get));
+  }
+
+  @Test
+  public void makeSureSingleQuoteStringsAreEvaluatedAsStrings() throws Exception {
+    assertFalse(runPredicate("55 == '7'", new HashMap<>()::get));
+    assertFalse(runPredicate("97 == 'a'", new HashMap<>()::get));
+  }
+
+  @Test
+  public void testNumericComparisonFunctions() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<String, Object>() {{
+      put("foo", "casey");
+      put("bar", "bar.casey.grok");
+      put("ip", "192.168.0.1");
+      put("num", 7);
+      put("num2", 8.5);
+      put("num3", 7);
+      put("num4", "8.5");
+      put("empty", "");
+      put("spaced", "metron is great");
+    }};
+    assertTrue(runPredicate("num == 7", variableMap::get));
+    assertTrue(runPredicate("num < num2", variableMap::get));
+    assertTrue(runPredicate("num < TO_DOUBLE(num2)", variableMap::get));
+    assertTrue(runPredicate("num < TO_DOUBLE(num4)", variableMap::get));
+    assertTrue(runPredicate("num < 100", variableMap::get));
+    assertTrue(runPredicate("num == num3", variableMap::get));
+    assertFalse(runPredicate("num == num2", variableMap::get));
+    assertTrue(runPredicate("num == num2 || true", variableMap::get));
+    assertFalse(runPredicate("num > num2", variableMap::get));
+    assertTrue(runPredicate("num == 7 && num > 2", variableMap::get));
+  }
+
+  @Test
+  public void positiveAndNegativeZeroAreEqual() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<String, Object>() {{
+      put("num", -0);
+    }};
+
+    Arrays.asList("!=", "==").forEach(op -> {
+      assertEquals("==".equals(op), runPredicate("num " + op + " 0", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("0 " + op + " -0", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("0 " + op + " -0d", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("-0 " + op + " 0", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("-0F " + op + " 0D", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("-0.F " + op + " 0", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("-0.F " + op + " 0F", variableMap::get));
+      assertEquals("==".equals(op), runPredicate("-0.D " + op + " 0D", variableMap::get));
+    });
+  }
+
+  @Test
+  public void naNIsNotEqualToNaN() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    Arrays.asList("!=", "==").forEach(op -> {
+      assertEquals("!=".equals(op), runPredicate("(0f/0f) " + op + " (0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(-0f/0f) " + op + " (0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(-0f/-0f) " + op + " (0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(-0f/-0f) " + op + " (-0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(-0f/-0f) " + op + " (-0f/-0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0f/-0f) " + op + " (0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0f/-0f) " + op + " (-0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0f/-0f) " + op + " (-0f/-0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0f/0f) " + op + " (-0f/0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0f/0d) " + op + " (-0f/-0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0d/-0f) " + op + " (0f/-0f)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(-0f/0f) " + op + " (0f/-0d)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(-0d/-0d) " + op + " (0d/-0d)", variableMap::get));
+      assertEquals("!=".equals(op), runPredicate("(0d/0d) " + op + " (0d/0d)", variableMap::get));
+    });
+  }
+
+  @Test
+  public void booleanComparisonTests() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<String, Object>() {{
+      put("t", true);
+      put("f", false);
+    }};
+
+    assertTrue(runPredicate("t != f", variableMap::get));
+    assertTrue(runPredicate("f != t", variableMap::get));
+    assertTrue(runPredicate("true != false", variableMap::get));
+    assertFalse(runPredicate("true != true", variableMap::get));
+    assertTrue(runPredicate("false != true", variableMap::get));
+    assertFalse(runPredicate("false != false", variableMap::get));
+
+    assertFalse(runPredicate("t == f", variableMap::get));
+    assertFalse(runPredicate("f == t", variableMap::get));
+    assertFalse(runPredicate("true == false", variableMap::get));
+    assertTrue(runPredicate("true == true", variableMap::get));
+    assertFalse(runPredicate("false == true", variableMap::get));
+    assertTrue(runPredicate("false == false", variableMap::get));
+
+    assertFalse(runPredicate("null == false", variableMap::get));
+    assertFalse(runPredicate("null == true", variableMap::get));
+    assertFalse(runPredicate("true == NULL", variableMap::get));
+    assertFalse(runPredicate("false == NULL", variableMap::get));
+  }
+
+  @Test
+  public void nullComparisonTests() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+
+    assertFalse(runPredicate("null == false", variableMap::get));
+    assertFalse(runPredicate("null == true", variableMap::get));
+    assertFalse(runPredicate("true == NULL", variableMap::get));
+    assertFalse(runPredicate("false == NULL", variableMap::get));
+    assertFalse(runPredicate("1 == NULL", variableMap::get));
+    assertFalse(runPredicate("'null' == NULL", variableMap::get));
+    assertFalse(runPredicate("'' == NULL", variableMap::get));
+    assertFalse(runPredicate("null == ''", variableMap::get));
+
+    assertTrue(runPredicate("NULL == null", variableMap::get));
+  }
+
+  @Test
+  public void precisionEqualityTests() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    assertEquals(0.1 + 0.2 == 0.3, runPredicate("0.1 + 0.2 == 0.3", variableMap::get));
+  }
+
+  @Test(expected = ParseException.class)
+  public void differentTypesShouldThrowErrorWhenUsingLT() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    runPredicate("1 < '1'", variableMap::get);
+  }
+
+  @Test(expected = ParseException.class)
+  public void differentTypesShouldThrowErrorWhenUsingLTE() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    runPredicate("'1' <= 1", variableMap::get);
+  }
+
+  @Test(expected = ParseException.class)
+  public void differentTypesShouldThrowErrorWhenUsingGT() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    runPredicate("1 > '1'", variableMap::get);
+  }
+
+  @Test(expected = ParseException.class)
+  public void differentTypesShouldThrowErrorWhenUsingGTE() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    runPredicate("'1' >= 1", variableMap::get);
+  }
+
+  @Test
+  public void differentTypesShouldThrowErrorWhenUsingComparisons() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    final Integer[] result = {0};
+
+    Stream.of("<", "<=", ">", ">=").forEach(op -> {
+      assertFalse(runPredicate("'1' " + op + " null", variableMap::get));
+    });
+  }
+
+  @Test
+  public void makeSurePrecisionIsProperlyHandled() throws Exception {
+    final Map<String, Object> variableMap = new HashMap<>();
+    {
+      assertEquals(1 == 1.00000001, runPredicate("1 == 1.00000001", variableMap::get));
+      assertEquals(1 < 1.00000001, runPredicate("1 < 1.00000001", variableMap::get));
+      assertEquals(1 <= 1.00000001, runPredicate("1 <= 1.00000001", variableMap::get));
+      assertEquals(1 > 1.00000001, runPredicate("1 > 1.00000001", variableMap::get));
+      assertEquals(1 >= 1.00000001, runPredicate("1 >= 1.00000001", variableMap::get));
+    }
+    {
+      assertEquals(1 == 1.00000001F, runPredicate("1 == 1.00000001F", variableMap::get));
+      assertEquals(1 < 1.00000001F, runPredicate("1 < 1.00000001F", variableMap::get));
+      assertEquals(1 <= 1.00000001F, runPredicate("1 <= 1.00000001F", variableMap::get));
+      assertEquals(1 > 1.00000001F, runPredicate("1 > 1.00000001F", variableMap::get));
+      assertEquals(1 >= 1.00000001F, runPredicate("1 >= 1.00000001F", variableMap::get));
+    }
+    {
+      assertEquals(1.00000001F == 1.00000001, runPredicate("1.00000001F == 1.00000001", variableMap::get));
+      assertEquals(1.00000001F < 1.00000001, runPredicate("1.00000001F < 1.00000001", variableMap::get));
+      assertEquals(1.00000001F <= 1.00000001, runPredicate("1.00000001F <= 1.00000001", variableMap::get));
+      assertEquals(1.00000001F > 1.00000001, runPredicate("1.00000001F > 1.00000001", variableMap::get));
+      assertEquals(1.00000001F >= 1.00000001, runPredicate("1.00000001F >= 1.00000001", variableMap::get));
+    }
+    {
+      assertEquals(-1L == -1.00000001F, runPredicate("-1L == -1.00000001F", variableMap::get));
+      assertEquals(-1L < -1.00000001F, runPredicate("-1L < -1.00000001F", variableMap::get));
+      assertEquals(-1L <= -1.00000001F, runPredicate("-1L <= -1.00000001F", variableMap::get));
+      assertEquals(-1L > -1.00000001F, runPredicate("-1L > -1.00000001F", variableMap::get));
+      assertEquals(-1L >= -1.00000001F, runPredicate("-1L >= -1.00000001F", variableMap::get));
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
index 2dafac0..3365643 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarCompilerTest.java
@@ -23,6 +23,7 @@ import org.apache.metron.common.dsl.Token;
 import org.apache.metron.common.dsl.VariableResolver;
 import org.apache.metron.common.dsl.functions.resolver.FunctionResolver;
 import org.apache.metron.common.stellar.evaluators.ArithmeticEvaluator;
+import org.apache.metron.common.stellar.evaluators.ComparisonExpressionWithOperatorEvaluator;
 import org.apache.metron.common.stellar.evaluators.NumberLiteralEvaluator;
 import org.apache.metron.common.stellar.generated.StellarParser;
 import org.junit.Before;
@@ -34,12 +35,14 @@ import org.powermock.modules.junit4.PowerMockRunner;
 import java.util.Stack;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.powermock.api.mockito.PowerMockito.*;
 
 
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({ArithmeticEvaluator.class, NumberLiteralEvaluator.class})
+@PrepareForTest({ArithmeticEvaluator.class, NumberLiteralEvaluator.class, ComparisonExpressionWithOperatorEvaluator.class})
 public class StellarCompilerTest {
   VariableResolver variableResolver;
   FunctionResolver functionResolver;
@@ -47,6 +50,7 @@ public class StellarCompilerTest {
   Stack<Token<?>> tokenStack;
   ArithmeticEvaluator arithmeticEvaluator;
   NumberLiteralEvaluator numberLiteralEvaluator;
+  ComparisonExpressionWithOperatorEvaluator comparisonExpressionWithOperatorEvaluator;
   StellarCompiler compiler;
 
   @SuppressWarnings("unchecked")
@@ -58,8 +62,9 @@ public class StellarCompilerTest {
     tokenStack = mock(Stack.class);
     arithmeticEvaluator = mock(ArithmeticEvaluator.class);
     numberLiteralEvaluator = mock(NumberLiteralEvaluator.class);
+    comparisonExpressionWithOperatorEvaluator = mock(ComparisonExpressionWithOperatorEvaluator.class);
 
-    compiler = new StellarCompiler(variableResolver, functionResolver, context, tokenStack, arithmeticEvaluator, numberLiteralEvaluator);
+    compiler = new StellarCompiler(variableResolver, functionResolver, context, tokenStack, arithmeticEvaluator, numberLiteralEvaluator, comparisonExpressionWithOperatorEvaluator);
   }
 
   @Test
@@ -76,6 +81,7 @@ public class StellarCompilerTest {
     verifyZeroInteractions(functionResolver);
     verifyZeroInteractions(context);
     verifyZeroInteractions(arithmeticEvaluator);
+    verifyZeroInteractions(comparisonExpressionWithOperatorEvaluator);
   }
 
   @Test
@@ -92,6 +98,7 @@ public class StellarCompilerTest {
     verifyZeroInteractions(functionResolver);
     verifyZeroInteractions(context);
     verifyZeroInteractions(arithmeticEvaluator);
+    verifyZeroInteractions(comparisonExpressionWithOperatorEvaluator);
   }
 
   @Test
@@ -108,6 +115,7 @@ public class StellarCompilerTest {
     verifyZeroInteractions(functionResolver);
     verifyZeroInteractions(context);
     verifyZeroInteractions(arithmeticEvaluator);
+    verifyZeroInteractions(comparisonExpressionWithOperatorEvaluator);
   }
 
   @Test
@@ -124,5 +132,26 @@ public class StellarCompilerTest {
     verifyZeroInteractions(functionResolver);
     verifyZeroInteractions(context);
     verifyZeroInteractions(arithmeticEvaluator);
+    verifyZeroInteractions(comparisonExpressionWithOperatorEvaluator);
+  }
+
+  @Test
+  public void properlyCompareTwoNumbers() throws Exception {
+    StellarParser.ComparisonExpressionWithOperatorContext ctx = mock(StellarParser.ComparisonExpressionWithOperatorContext.class);
+    StellarParser.ComparisonOpContext mockOp = mock(StellarParser.ComparisonOpContext.class);
+    when(ctx.comp_operator()).thenReturn(mockOp);
+
+    compiler.exitComparisonExpressionWithOperator(ctx);
+
+    verify(comparisonExpressionWithOperatorEvaluator).evaluate(any(Token.class), any(Token.class), eq(mockOp));
+    verify(tokenStack, times(2)).pop();
+    verify(tokenStack).push(any());
+    verify(tokenStack, times(2)).empty();
+    verifyNoMoreInteractions(tokenStack);
+    verifyZeroInteractions(numberLiteralEvaluator);
+    verifyZeroInteractions(variableResolver);
+    verifyZeroInteractions(functionResolver);
+    verifyZeroInteractions(context);
+    verifyZeroInteractions(arithmeticEvaluator);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarPredicateProcessorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarPredicateProcessorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarPredicateProcessorTest.java
new file mode 100644
index 0000000..c0165a3
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarPredicateProcessorTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.stellar;
+
+import org.apache.metron.common.dsl.ParseException;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class StellarPredicateProcessorTest {
+  @SuppressWarnings("EmptyCatchBlock")
+  @Test
+  public void testValidation() throws Exception {
+    StellarPredicateProcessor processor = new StellarPredicateProcessor();
+    try {
+      processor.validate("enrichedField1 == 'enrichedValue1");
+      fail("Invalid rule found to be valid - unclosed single quotes.");
+    } catch(ParseException e) {}
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
index 2163f85..2eaa60d 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/StellarTest.java
@@ -21,7 +21,6 @@ package org.apache.metron.common.stellar;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.metron.common.dsl.ParseException;
 import org.apache.metron.common.dsl.Stellar;
 import org.apache.metron.common.dsl.StellarFunction;
 import org.junit.Assert;
@@ -199,8 +198,8 @@ public class StellarTest {
       Assert.assertEquals("two", run(query, new HashMap<>()));
     }
     {
-      String query = "if 1 == 1.000001 then 'one' else 'two'";
-      Assert.assertEquals("one", run(query, new HashMap<>()));
+      String query = "if 1 == 1.0000001 then 'one' else 'two'";
+      Assert.assertEquals("two", run(query, new HashMap<>()));
     }
     {
       String query = "if one < two then 'one' else 'two'";
@@ -208,7 +207,7 @@ public class StellarTest {
     }
     {
       String query = "if one == very_nearly_one then 'one' else 'two'";
-      Assert.assertEquals("one", run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.000001)));
+      Assert.assertEquals("two", run(query, ImmutableMap.of("one", 1, "very_nearly_one", 1.0000001)));
     }
     {
       String query = "1 < 2 ? 'one' : 'two'";
@@ -386,25 +385,6 @@ public class StellarTest {
   }
 
   @Test
-  public void testValidation() throws Exception {
-    StellarPredicateProcessor processor = new StellarPredicateProcessor();
-    try {
-      processor.validate("'foo'");
-      Assert.fail("Invalid rule found to be valid - lone value.");
-    }
-    catch(ParseException e) {
-
-    }
-    try {
-      processor.validate("enrichedField1 == 'enrichedValue1");
-      Assert.fail("Invalid rule found to be valid - unclosed single quotes.");
-    }
-    catch(ParseException e) {
-
-    }
-  }
-
-  @Test
   public void testBooleanOps() throws Exception {
     final Map<String, String> variableMap = new HashMap<String, String>() {{
       put("foo", "casey");
@@ -463,31 +443,6 @@ public class StellarTest {
   }
 
   @Test
-  public void testNumericComparisonFunctions() throws Exception {
-    final Map<String, Object> variableMap = new HashMap<String, Object>() {{
-      put("foo", "casey");
-      put("bar", "bar.casey.grok");
-      put("ip", "192.168.0.1");
-      put("num", 7);
-      put("num2", 8.5);
-      put("num3", 7);
-      put("num4", "8.5");
-      put("empty", "");
-      put("spaced", "metron is great");
-    }};
-    Assert.assertTrue(runPredicate("num == 7", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num < num2", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num < TO_DOUBLE(num2)", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num < TO_DOUBLE(num4)", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num < 100", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num == num3", v -> variableMap.get(v)));
-    Assert.assertFalse(runPredicate("num == num2", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num == num2 || true", v -> variableMap.get(v)));
-    Assert.assertFalse(runPredicate("num > num2", v -> variableMap.get(v)));
-    Assert.assertTrue(runPredicate("num == 7 && num > 2", v -> variableMap.get(v)));
-  }
-
-  @Test
   public void testLogicalFunctions() throws Exception {
     final Map<String, String> variableMap = new HashMap<String, String>() {{
       put("foo", "casey");

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluatorTest.java
new file mode 100644
index 0000000..612d311
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonExpressionWithOperatorEvaluatorTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@SuppressWarnings({"unchecked"})
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ComparisonExpressionWithOperatorEvaluator.class, ComparisonExpressionWithOperatorEvaluator.Strategy.class})
+public class ComparisonExpressionWithOperatorEvaluatorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  final ComparisonExpressionWithOperatorEvaluator evaluator = ComparisonExpressionWithOperatorEvaluator.INSTANCE;
+
+  @Test
+  public void evaluateEqShouldProperlyCallEqualityOperatorsEvaluator() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1D);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    Token<Boolean> evaluated = evaluator.evaluate(left, right, op);
+
+    assertTrue(evaluated.getValue());
+  }
+
+  @Test
+  public void evaluateNotEqShouldProperlyCallEqualityOperatorsEvaluator() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1D);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.NEQ()).thenReturn(mock(TerminalNode.class));
+
+    Token<Boolean> evaluated = evaluator.evaluate(left, right, op);
+
+    assertFalse(evaluated.getValue());
+  }
+
+  @Test
+  public void evaluateLessThanEqShouldProperlyCallEqualityOperatorsEvaluator() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(0D);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.LTE()).thenReturn(mock(TerminalNode.class));
+
+    Token<Boolean> evaluated = evaluator.evaluate(left, right, op);
+
+    assertTrue(evaluated.getValue());
+  }
+
+  @Test
+  public void unexpectedOperatorShouldThrowException() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unsupported operations. The following expression is invalid: ");
+
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(0D);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+
+    evaluator.evaluate(left, right, op);
+  }
+
+  @Test
+  public void nonExpectedOperatorShouldThrowException() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unsupported operations. The following expression is invalid: ");
+
+    Token<String> left = mock(Token.class);
+    when(left.getValue()).thenReturn("adsf");
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.LTE()).thenReturn(mock(TerminalNode.class));
+
+    evaluator.evaluate(left, right, op);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluatorTest.java
new file mode 100644
index 0000000..3617e44
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/ComparisonOperatorsEvaluatorTest.java
@@ -0,0 +1,446 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.metron.common.dsl.ParseException;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.io.Serializable;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@SuppressWarnings("ALL")
+public class ComparisonOperatorsEvaluatorTest {
+  @Rule
+  public final ExpectedException exception = ExpectedException.none();
+
+  ComparisonExpressionEvaluator evaluator;
+
+  @Before
+  public void setUp() throws Exception {
+    evaluator = new ComparisonOperatorsEvaluator();
+  }
+
+  @Test
+  public void nonSupportedOperatorThrowsExceptionNonNumbericComparable() throws Exception {
+    Token<String> left = mock(Token.class);
+    when(left.getValue()).thenReturn("b");
+
+    Token<String> right = mock(Token.class);
+    when(right.getValue()).thenReturn("a");
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unsupported operator: " + op);
+
+    evaluator.evaluate(left, right, op);
+  }
+
+  @Test
+  public void nonSupportedOperatorThrowsExceptionNumbericComparison() throws Exception {
+    Token<Long> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1L);
+
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(0L);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unsupported operator: " + op);
+
+    evaluator.evaluate(left, right, op);
+  }
+
+  @Test
+  public void leftIsNullThenThrowException() throws Exception {
+    Token<Long> left = mock(Token.class);
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1L);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.LT()).thenReturn(mock(TerminalNode.class));
+
+    assertFalse(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void rightIsNullThenReturnFalse() throws Exception {
+    Token<Long> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1L);
+    Token<Long> right = mock(Token.class);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.LT()).thenReturn(mock(TerminalNode.class));
+
+    assertFalse(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void rightAndLeftIsNullThenReturnFalse() throws Exception {
+    Token<Long> left = mock(Token.class);
+    Token<Long> right = mock(Token.class);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.LT()).thenReturn(mock(TerminalNode.class));
+
+    assertFalse(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void throwParseExceptionWhenTryingToCompareNonComparable() throws Exception {
+    exception.expect(ParseException.class);
+    exception.expectMessage("Unsupported operations. The following expression is invalid: ");
+
+    Token<Serializable> left = mock(Token.class);
+    when(left.getValue()).thenReturn(mock(Serializable.class));
+
+    Token<Serializable> right = mock(Token.class);
+    when(right.getValue()).thenReturn(mock(Serializable.class));
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.LT()).thenReturn(mock(TerminalNode.class));
+
+    evaluator.evaluate(left, right, op);
+  }
+
+  @Test
+  public void makeSureAllOperatorsProperlyWorkForLongs() throws Exception {
+    Token<Long> left = mock(Token.class);
+    when(left.getValue()).thenReturn(0L);
+
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1L);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsProperlyWorkForDoubles() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(0D);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsProperlyWorkForFloats() throws Exception {
+    Token<Float> left = mock(Token.class);
+    when(left.getValue()).thenReturn(0F);
+
+    Token<Float> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1F);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsProperlyWorkForInts() throws Exception {
+    Token<Integer> left = mock(Token.class);
+    when(left.getValue()).thenReturn(0);
+
+    Token<Integer> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsWorkForMixedTypesDoublesLong() throws Exception {
+    Token<Long> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1L);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1.0000001D);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertTrue(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertFalse(evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsWorkForMixedTypesDoublesFloat() throws Exception {
+    final double leftValue = 1.0000001D;
+    final float rightValue = 1.0000001F;
+
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(leftValue);
+
+    Token<Float> right = mock(Token.class);
+    when(right.getValue()).thenReturn(rightValue);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue < rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue <= rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue > rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue >= rightValue, evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsWorkForMixedTypesFloatIntegers() throws Exception {
+    final int leftValue = 1;
+    final float rightValue = 1.0000001F;
+
+    Token<Integer> left = mock(Token.class);
+    when(left.getValue()).thenReturn(leftValue);
+
+    Token<Float> right = mock(Token.class);
+    when(right.getValue()).thenReturn(rightValue);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue < rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue <= rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue > rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue >= rightValue, evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsWorkForMixedTypesFloatIntegers2() throws Exception {
+    final int leftValue = 1;
+    final float rightValue = 1.00000001F;
+
+    Token<Integer> left = mock(Token.class);
+    when(left.getValue()).thenReturn(leftValue);
+
+    Token<Float> right = mock(Token.class);
+    when(right.getValue()).thenReturn(rightValue);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue < rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue <= rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue > rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue >= rightValue, evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsWorkForMixedTypesLongIntegers() throws Exception {
+    final int leftValue = 1;
+    final long rightValue = 3L;
+
+    Token<Integer> left = mock(Token.class);
+    when(left.getValue()).thenReturn(leftValue);
+
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(rightValue);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue < rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue <= rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue > rightValue, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue >= rightValue, evaluator.evaluate(left, right, op));
+    }
+  }
+
+  @Test
+  public void makeSureAllOperatorsWorkForNonIntegerComparableTypes() throws Exception {
+    final String leftValue = "a";
+    final String rightValue = "b";
+
+    Token<String> left = mock(Token.class);
+    when(left.getValue()).thenReturn(leftValue);
+
+    Token<String> right = mock(Token.class);
+    when(right.getValue()).thenReturn(rightValue);
+
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue.compareTo(rightValue) < 0, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.LTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue.compareTo(rightValue) <= 0, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GT()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue.compareTo(rightValue) > 0, evaluator.evaluate(left, right, op));
+    }
+    {
+      StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+      when(op.GTE()).thenReturn(mock(TerminalNode.class));
+      assertEquals(leftValue.compareTo(rightValue) >= 0, evaluator.evaluate(left, right, op));
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluatorTest.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluatorTest.java
new file mode 100644
index 0000000..efa7db6
--- /dev/null
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/stellar/evaluators/EqualityOperatorsEvaluatorTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.metron.common.stellar.evaluators;
+
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.metron.common.dsl.Token;
+import org.apache.metron.common.stellar.generated.StellarParser;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@SuppressWarnings({"unchecked"})
+public class EqualityOperatorsEvaluatorTest {
+  ComparisonExpressionEvaluator evaluator;
+
+  @Before
+  public void setUp() throws Exception {
+    evaluator = new EqualityOperatorsEvaluator();
+  }
+
+  @Test
+  public void leftAndRightNullShouldBeTrue() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(null);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(null);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    boolean evaluated = evaluator.evaluate(left, right, op);
+
+    assertTrue(evaluated);
+  }
+
+  @Test
+  public void leftNullAndRightNotShouldBeFalse() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(null);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    boolean evaluated = evaluator.evaluate(left, right, op);
+
+    assertFalse(evaluated);
+  }
+
+  @Test
+  public void leftNotNullAndRightNullShouldBeFalse() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1D);
+
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(null);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    boolean evaluated = evaluator.evaluate(left, right, op);
+
+    assertFalse(evaluated);
+  }
+
+  @Test
+  public void eqTestForTwoLongs() throws Exception {
+    Token<Long> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1L);
+
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1L);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertTrue(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void eqTestForTwoDoubles() throws Exception {
+    Token<Double> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1D);
+
+    Token<Double> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1D);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertTrue(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void eqTestForTwoFloats() throws Exception {
+    Token<Float> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1F);
+
+    Token<Float> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1F);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertTrue(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void eqTestForTwoIntegers() throws Exception {
+    Token<Integer> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1);
+
+    Token<Integer> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertTrue(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void eqTestForTwoStrings() throws Exception {
+    Token<String> left = mock(Token.class);
+    when(left.getValue()).thenReturn("1");
+
+    Token<String> right = mock(Token.class);
+    when(right.getValue()).thenReturn("1");
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertTrue(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void eqTestForUnlikeTypes() throws Exception {
+    Token<String> left = mock(Token.class);
+    when(left.getValue()).thenReturn("1");
+
+    Token<Long> right = mock(Token.class);
+    when(right.getValue()).thenReturn(1L);
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertFalse(evaluator.evaluate(left, right, op));
+  }
+
+  @Test
+  public void eqTestForUnlikeTypesLongString() throws Exception {
+    Token<Long> left = mock(Token.class);
+    when(left.getValue()).thenReturn(1L);
+
+    Token<String> right = mock(Token.class);
+    when(right.getValue()).thenReturn("1");
+
+    StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class);
+    when(op.EQ()).thenReturn(mock(TerminalNode.class));
+
+    assertFalse(evaluator.evaluate(left, right, op));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/56ff50c3/metron-platform/metron-common/src/test/java/org/apache/metron/common/utils/StellarProcessorUtils.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/test/java/org/apache/metron/common/utils/StellarProcessorUtils.java b/metron-platform/metron-common/src/test/java/org/apache/metron/common/utils/StellarProcessorUtils.java
index 7ef84ea..8a8e32a 100644
--- a/metron-platform/metron-common/src/test/java/org/apache/metron/common/utils/StellarProcessorUtils.java
+++ b/metron-platform/metron-common/src/test/java/org/apache/metron/common/utils/StellarProcessorUtils.java
@@ -18,16 +18,19 @@
 
 package org.apache.metron.common.utils;
 
+import org.apache.metron.common.dsl.Context;
+import org.apache.metron.common.dsl.MapVariableResolver;
+import org.apache.metron.common.dsl.StellarFunctions;
+import org.apache.metron.common.dsl.VariableResolver;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import org.apache.metron.common.dsl.*;
 import org.apache.metron.common.stellar.StellarPredicateProcessor;
 import org.apache.metron.common.stellar.StellarProcessor;
 import org.junit.Assert;
-import org.junit.Test;
 
-import java.util.*;
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Spliterators;
 import java.util.function.Consumer;
 import java.util.function.IntConsumer;
 import java.util.function.Supplier;
@@ -37,25 +40,25 @@ import java.util.stream.StreamSupport;
 
 public class StellarProcessorUtils {
 
-  /**
-   * This ensures the basic contract of a stellar expression is adhered to:
-   * 1. Validate works on the expression
-   * 2. The output can be serialized and deserialized properly
-   *
-   * @param rule
-   * @param variables
-   * @param context
-   * @return
-   */
-  public static Object run(String rule, Map<String, Object> variables, Context context) {
-    StellarProcessor processor = new StellarProcessor();
-    Assert.assertTrue(rule + " not valid.", processor.validate(rule, context));
-    Object ret = processor.parse(rule, x -> variables.get(x), StellarFunctions.FUNCTION_RESOLVER(), context);
-    byte[] raw = SerDeUtils.toBytes(ret);
-    Object actual = SerDeUtils.fromBytes(raw, Object.class);
-    Assert.assertEquals(ret, actual);
-    return ret;
-  }
+    /**
+     * This ensures the basic contract of a stellar expression is adhered to:
+     * 1. Validate works on the expression
+     * 2. The output can be serialized and deserialized properly
+     *
+     * @param rule
+     * @param variables
+     * @param context
+     * @return
+     */
+    public static Object run(String rule, Map<String, Object> variables, Context context) {
+        StellarProcessor processor = new StellarProcessor();
+        Assert.assertTrue(rule + " not valid.", processor.validate(rule, context));
+        Object ret = processor.parse(rule, x -> variables.get(x), StellarFunctions.FUNCTION_RESOLVER(), context);
+        byte[] raw = SerDeUtils.toBytes(ret);
+        Object actual = SerDeUtils.fromBytes(raw, Object.class);
+        Assert.assertEquals(ret, actual);
+        return ret;
+    }
 
   public static Object run(String rule, Map<String, Object> variables) {
     return run(rule, variables, Context.EMPTY_CONTEXT());


Mime
View raw message