Repository: metron Updated Branches: refs/heads/master 63cd41433 -> acab9436d
METRON-1579: Stellar should return the expression that failed in the exception closes apache/incubator-metron#1033 Project: http://git-wip-us.apache.org/repos/asf/metron/repo Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/acab9436 Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/acab9436 Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/acab9436 Branch: refs/heads/master Commit: acab9436d028cf047e21948f604f5dab1507a983 Parents: 63cd414 Author: cstella <ceste...@gmail.com> Authored: Thu May 31 10:40:17 2018 -0700 Committer: cstella <ceste...@gmail.com> Committed: Thu May 31 10:40:17 2018 -0700 ---------------------------------------------------------------------- .../profiler/client/stellar/GetProfileTest.java | 3 ++- .../client/stellar/ProfilerFunctionsTest.java | 15 ++++++----- .../StellarStatisticsFunctionsTest.java | 5 ++-- .../sampling/SamplerFunctionsTest.java | 3 ++- .../adapters/stellar/StellarAdapter.java | 14 +++++++++- .../management/IndexingConfigFunctionsTest.java | 7 ++--- .../management/ThreatTriageFunctionsTest.java | 7 ++--- .../stellar/common/BaseStellarProcessor.java | 28 ++++++++++++++++++-- .../common/StellarPredicateProcessor.java | 6 +++++ .../shell/specials/AssignmentCommandTest.java | 7 +++-- .../dsl/functions/OrdinalFunctionsTest.java | 9 ++++--- 11 files changed, 78 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/GetProfileTest.java ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/GetProfileTest.java b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/GetProfileTest.java index 6ed6e64..0eacb42 100644 --- a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/GetProfileTest.java +++ b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/GetProfileTest.java @@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.client.HTableInterface; import org.apache.metron.hbase.mock.MockHBaseTableProvider; import org.apache.metron.profiler.client.ProfileWriter; import org.apache.metron.stellar.dsl.Context; +import org.apache.metron.stellar.dsl.ParseException; import org.apache.metron.stellar.dsl.functions.resolver.SimpleFunctionResolver; import org.apache.metron.stellar.dsl.functions.resolver.SingletonFunctionResolver; import org.apache.metron.profiler.ProfileMeasurement; @@ -266,7 +267,7 @@ public class GetProfileTest { /** * Initialization should fail if the required context values are missing. */ - @Test(expected = IllegalStateException.class) + @Test(expected = ParseException.class) public void testMissingContext() { Context empty = Context.EMPTY_CONTEXT(); http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java index e1c6aa8..1670e8c 100644 --- a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java +++ b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java @@ -25,6 +25,7 @@ import org.apache.metron.profiler.StandAloneProfiler; import org.apache.metron.stellar.common.DefaultStellarStatefulExecutor; import org.apache.metron.stellar.common.StellarStatefulExecutor; import org.apache.metron.stellar.dsl.Context; +import org.apache.metron.stellar.dsl.ParseException; import org.apache.metron.stellar.dsl.functions.resolver.SimpleFunctionResolver; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -145,12 +146,12 @@ public class ProfilerFunctionsTest { assertEquals(0, profiler.getRouteCount()); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerInitNoArgs() { run("PROFILER_INIT()", StandAloneProfiler.class); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerInitInvalidArg() { run("PROFILER_INIT({ \"invalid\": 2 })", StandAloneProfiler.class); } @@ -273,17 +274,17 @@ public class ProfilerFunctionsTest { assertEquals(0, profiler.getRouteCount()); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerApplyWithNoArgs() { run("PROFILER_APPLY()", StandAloneProfiler.class); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerApplyWithInvalidArg() { run("PROFILER_APPLY(undefined)", StandAloneProfiler.class); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerApplyWithNullMessage() { // initialize the profiler @@ -321,12 +322,12 @@ public class ProfilerFunctionsTest { assertEquals(Collections.emptyList(), measurement.get("groups")); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerFlushNoArgs() { run("PROFILER_FLUSH()", StandAloneProfiler.class); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testProfilerFlushInvalidArg() { run("PROFILER_FLUSH(undefined)", StandAloneProfiler.class); } http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/StellarStatisticsFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/StellarStatisticsFunctionsTest.java b/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/StellarStatisticsFunctionsTest.java index a026bf2..e855cb7 100644 --- a/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/StellarStatisticsFunctionsTest.java +++ b/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/StellarStatisticsFunctionsTest.java @@ -28,6 +28,7 @@ import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.apache.metron.stellar.dsl.Context; import org.apache.metron.stellar.dsl.DefaultVariableResolver; +import org.apache.metron.stellar.dsl.ParseException; import org.apache.metron.stellar.dsl.StellarFunctions; import org.apache.metron.stellar.common.StellarProcessor; import org.apache.metron.common.utils.SerDeUtils; @@ -172,7 +173,7 @@ public class StellarStatisticsFunctionsTest { values.stream().forEach(val -> run(format("STATS_ADD (stats, %f)", val), variables)); } - @Test(expected=IllegalStateException.class) + @Test(expected=ParseException.class) public void testOverflow() throws Exception { run(format("STATS_ADD(STATS_INIT(), %f)", (Double.MAX_VALUE + 1)), new HashMap<>()); } @@ -354,7 +355,7 @@ public class StellarStatisticsFunctionsTest { assertEquals(summaryStats.getSumOfLogs(), (Double) actual, 0.1); } - @Test(expected = UnsupportedOperationException.class) + @Test(expected = ParseException.class) public void testSumLogsWithWindow() throws Exception { statsInit(100); run("STATS_SUM_LOGS(stats)", variables); http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/sampling/SamplerFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/sampling/SamplerFunctionsTest.java b/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/sampling/SamplerFunctionsTest.java index 851ba67..fe607f7 100644 --- a/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/sampling/SamplerFunctionsTest.java +++ b/metron-analytics/metron-statistics/src/test/java/org/apache/metron/statistics/sampling/SamplerFunctionsTest.java @@ -22,6 +22,7 @@ package org.apache.metron.statistics.sampling; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import org.apache.metron.stellar.common.utils.StellarProcessorUtils; +import org.apache.metron.stellar.dsl.ParseException; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -69,7 +70,7 @@ public class SamplerFunctionsTest { Assert.assertEquals(10, s.getSize()); } - @Test(expected=IllegalStateException.class) + @Test(expected=ParseException.class) public void testInvalidInit(){ String stmt = "SAMPLE_INIT(size)"; Sampler s = (Sampler) StellarProcessorUtils.run(stmt, ImmutableMap.of("size", -10 )); http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-platform/metron-enrichment/src/main/java/org/apache/metron/enrichment/adapters/stellar/StellarAdapter.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-enrichment/src/main/java/org/apache/metron/enrichment/adapters/stellar/StellarAdapter.java b/metron-platform/metron-enrichment/src/main/java/org/apache/metron/enrichment/adapters/stellar/StellarAdapter.java index 0aabd38..a5feac0 100644 --- a/metron-platform/metron-enrichment/src/main/java/org/apache/metron/enrichment/adapters/stellar/StellarAdapter.java +++ b/metron-platform/metron-enrichment/src/main/java/org/apache/metron/enrichment/adapters/stellar/StellarAdapter.java @@ -21,11 +21,15 @@ import static org.apache.metron.enrichment.bolt.GenericEnrichmentBolt.STELLAR_CO import java.io.Serializable; import java.lang.invoke.MethodHandles; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; + +import com.google.common.base.Joiner; import org.apache.metron.common.configuration.enrichment.SensorEnrichmentConfig; import org.apache.metron.common.configuration.enrichment.handler.ConfigHandler; import org.apache.metron.enrichment.bolt.CacheKey; @@ -92,6 +96,7 @@ public class StellarAdapter implements EnrichmentAdapter<CacheKey>,Serializable } } + public static JSONObject process( Map<String, Object> message , ConfigHandler handler , String field @@ -112,7 +117,14 @@ public class StellarAdapter implements EnrichmentAdapter<CacheKey>,Serializable if (kv.getValue() instanceof String) { long startTime = System.currentTimeMillis(); String stellarStatement = (String) kv.getValue(); - Object o = processor.parse(stellarStatement, resolver, StellarFunctions.FUNCTION_RESOLVER(), stellarContext); + Object o = null; + try { + o = processor.parse(stellarStatement, resolver, StellarFunctions.FUNCTION_RESOLVER(), stellarContext); + } + catch(Exception e) { + _LOG.error(e.getMessage(), e); + throw e; + } if (slowLogThreshold != null && _PERF_LOG.isDebugEnabled()) { long duration = System.currentTimeMillis() - startTime; if (duration > slowLogThreshold) { http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-platform/metron-management/src/test/java/org/apache/metron/management/IndexingConfigFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-management/src/test/java/org/apache/metron/management/IndexingConfigFunctionsTest.java b/metron-platform/metron-management/src/test/java/org/apache/metron/management/IndexingConfigFunctionsTest.java index c931df5..6ecf90f 100644 --- a/metron-platform/metron-management/src/test/java/org/apache/metron/management/IndexingConfigFunctionsTest.java +++ b/metron-platform/metron-management/src/test/java/org/apache/metron/management/IndexingConfigFunctionsTest.java @@ -22,6 +22,7 @@ import org.apache.metron.common.configuration.IndexingConfigurations; import org.apache.metron.stellar.common.shell.VariableResult; import org.apache.metron.stellar.dsl.Context; import org.apache.metron.stellar.dsl.DefaultVariableResolver; +import org.apache.metron.stellar.dsl.ParseException; import org.apache.metron.stellar.dsl.StellarFunctions; import org.apache.metron.stellar.common.StellarProcessor; import org.junit.Assert; @@ -75,7 +76,7 @@ public class IndexingConfigFunctionsTest { Assert.assertEquals(2, IndexingConfigurations.getBatchTimeout((Map<String, Object>) config.get("hdfs"))); } - @Test(expected=IllegalStateException.class) + @Test(expected=ParseException.class) public void testSetBatchBad() { Map<String,Object> variables = new HashMap<String,Object>(){{ put("config",null); @@ -94,7 +95,7 @@ public class IndexingConfigFunctionsTest { Assert.assertTrue(IndexingConfigurations.isEnabled((Map<String, Object>) config.get("hdfs"))); } - @Test(expected=IllegalStateException.class) + @Test(expected=ParseException.class) public void testSetEnabledBad() { Map<String,Object> variables = new HashMap<String,Object>(){{ put("config",null); @@ -113,7 +114,7 @@ public class IndexingConfigFunctionsTest { Assert.assertEquals("foo", IndexingConfigurations.getIndex((Map<String, Object>)config.get("hdfs"), null)); } - @Test(expected= IllegalStateException.class) + @Test(expected= ParseException.class) public void testSetIndexBad() { Map<String,Object> variables = new HashMap<String,Object>(){{ put("config",null); http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-platform/metron-management/src/test/java/org/apache/metron/management/ThreatTriageFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-management/src/test/java/org/apache/metron/management/ThreatTriageFunctionsTest.java b/metron-platform/metron-management/src/test/java/org/apache/metron/management/ThreatTriageFunctionsTest.java index e281038..0809dcf 100644 --- a/metron-platform/metron-management/src/test/java/org/apache/metron/management/ThreatTriageFunctionsTest.java +++ b/metron-platform/metron-management/src/test/java/org/apache/metron/management/ThreatTriageFunctionsTest.java @@ -26,6 +26,7 @@ import org.apache.metron.stellar.common.shell.VariableResult; import org.apache.metron.stellar.dsl.Context; import org.apache.metron.stellar.dsl.DefaultVariableResolver; import org.apache.metron.stellar.dsl.MapVariableResolver; +import org.apache.metron.stellar.dsl.ParseException; import org.apache.metron.stellar.dsl.StellarFunctions; import org.apache.metron.threatintel.triage.ThreatTriageProcessor; import org.junit.Assert; @@ -173,7 +174,7 @@ public class ThreatTriageFunctionsTest { Assert.assertEquals(20.0, greater.getScore().doubleValue(), 1e-6 ); } - @Test(expected=IllegalStateException.class) + @Test(expected=ParseException.class) public void testAddMalformed() { Object o = run( "THREAT_TRIAGE_ADD(config, { 'rule': SHELL_GET_EXPRESSION('foo'), 'score' : 10 } )" @@ -398,7 +399,7 @@ Aggregation: MAX*/ Assert.assertEquals(testPrintEmptyExpected, out); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testPrintNull() { Map<String,Object> variables = new HashMap<String,Object>(){{ put("config", null); @@ -447,7 +448,7 @@ Aggregation: MAX*/ Assert.assertEquals(1, engine.getRiskLevelRules().size()); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = ParseException.class) public void testTriageInitWithBadArg() { run("THREAT_TRIAGE_INIT(missing)"); } http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/BaseStellarProcessor.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/BaseStellarProcessor.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/BaseStellarProcessor.java index 941c66d..7ec3d5b 100644 --- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/BaseStellarProcessor.java +++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/BaseStellarProcessor.java @@ -21,10 +21,16 @@ package org.apache.metron.stellar.common; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine; +import com.google.common.base.Joiner; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.TokenStream; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -138,17 +144,35 @@ public class BaseStellarProcessor<T> { try { expression = expressionCache.get(rule, r -> compile(r)); } catch (Throwable e) { - throw new ParseException("Unable to parse: " + rule + " due to: " + e.getMessage(), e); + throw createException(rule, variableResolver, e); } try { return clazz.cast(expression .apply(new StellarCompiler.ExpressionState(context, functionResolver, variableResolver))); - }finally { + } + catch(Throwable e) { + throw createException(rule, variableResolver, e); + } + finally { // always reset the activity type context.setActivityType(null); } } + private ParseException createException(String rule, VariableResolver resolver, Throwable t) { + String message = "Unable to parse: " + rule + " due to: " + t.getMessage(); + Set<String> variablesUsed = variablesUsed(rule); + if(variablesUsed.isEmpty()) { + return new ParseException(message, t); + } + List<Map.Entry<String, Object>> messagesUsed = new ArrayList<>(variablesUsed.size()); + for(String v : variablesUsed) { + Optional<Object> resolved = Optional.ofNullable(resolver.resolve(v)); + messagesUsed.add(new AbstractMap.SimpleEntry<>(v, resolved.orElse("missing"))); + } + return new ParseException(message + " with relevant variables " + Joiner.on(",").join(messagesUsed), t); + } + /** * Parses and evaluates the given Stellar expression, {@code rule}. * @param rule The Stellar expression to parse and evaluate. http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarPredicateProcessor.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarPredicateProcessor.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarPredicateProcessor.java index c27d0cd..a8586b9 100644 --- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarPredicateProcessor.java +++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/StellarPredicateProcessor.java @@ -62,5 +62,11 @@ public class StellarPredicateProcessor extends BaseStellarProcessor<Boolean> { // predicate must return boolean throw new IllegalArgumentException(String.format("The rule '%s' does not return a boolean value.", rule), e); } + catch(Exception e) { + if(e.getCause() != null && e.getCause() instanceof ClassCastException) { + throw new IllegalArgumentException(String.format("The rule '%s' does not return a boolean value.", rule), e.getCause()); + } + throw e; + } } } http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/shell/specials/AssignmentCommandTest.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/shell/specials/AssignmentCommandTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/shell/specials/AssignmentCommandTest.java index 1b5c9d5..9a05efb 100644 --- a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/shell/specials/AssignmentCommandTest.java +++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/shell/specials/AssignmentCommandTest.java @@ -22,6 +22,7 @@ package org.apache.metron.stellar.common.shell.specials; import org.apache.metron.stellar.common.shell.DefaultStellarShellExecutor; import org.apache.metron.stellar.common.shell.StellarShellExecutor; import org.apache.metron.stellar.common.shell.StellarResult; +import org.apache.metron.stellar.dsl.ParseException; import org.junit.Before; import org.junit.Test; @@ -155,12 +156,14 @@ public class AssignmentCommandTest { */ @Test public void testErrorMessageWhenAssignmentFails() { - StellarResult result = command.execute("x := 0/0", executor); + String stmt = "0/0"; + StellarResult result = command.execute("x := " + stmt, executor); // validate the result assertTrue(result.isError()); assertTrue(result.getException().isPresent()); - assertEquals(ArithmeticException.class, result.getException().get().getClass()); + assertEquals(ParseException.class, result.getException().get().getClass()); + assertTrue(result.getException().get().getMessage().contains(stmt)); } @Test http://git-wip-us.apache.org/repos/asf/metron/blob/acab9436/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/OrdinalFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/OrdinalFunctionsTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/OrdinalFunctionsTest.java index e405c7f..fb18c39 100644 --- a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/OrdinalFunctionsTest.java +++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/OrdinalFunctionsTest.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap; import org.apache.metron.stellar.common.StellarProcessor; import org.apache.metron.stellar.dsl.Context; import org.apache.metron.stellar.dsl.DefaultVariableResolver; +import org.apache.metron.stellar.dsl.ParseException; import org.apache.metron.stellar.dsl.StellarFunctions; import org.junit.Assert; import org.junit.Before; @@ -172,8 +173,8 @@ public class OrdinalFunctionsTest { try { res = run("MAX(input_list)", ImmutableMap.of("input_list", inputList)); - } catch(IllegalStateException e) { - Assert.assertThat(e.getMessage(), is("Incomparable objects were submitted to MAX: class java.lang.String is incomparable to class java.lang.Long")); + } catch(ParseException e) { + Assert.assertTrue(e.getMessage().contains("Incomparable objects were submitted to MAX: class java.lang.String is incomparable to class java.lang.Long")); Assert.assertNull(res); } } @@ -212,8 +213,8 @@ public class OrdinalFunctionsTest { try { res = run("MIN(input_list)", ImmutableMap.of("input_list", inputList)); - } catch(IllegalStateException e) { - Assert.assertThat(e.getMessage(), is("Noncomparable object type org.apache.metron.stellar.dsl.functions.OrdinalFunctionsTest$1TestObject submitted to MIN")); + } catch(ParseException e) { + Assert.assertTrue(e.getMessage().contains("Noncomparable object type org.apache.metron.stellar.dsl.functions.OrdinalFunctionsTest$1TestObject submitted to MIN")); Assert.assertNull(res); } }