mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 22:57:16 -04:00
parent
120b6a7d04
commit
4b5dc343ae
4 changed files with 135 additions and 6 deletions
|
@ -68,6 +68,7 @@ task javaTests(type: Test) {
|
||||||
exclude '/org/logstash/RSpecTests.class'
|
exclude '/org/logstash/RSpecTests.class'
|
||||||
exclude '/org/logstash/config/ir/ConfigCompilerTest.class'
|
exclude '/org/logstash/config/ir/ConfigCompilerTest.class'
|
||||||
exclude '/org/logstash/config/ir/CompiledPipelineTest.class'
|
exclude '/org/logstash/config/ir/CompiledPipelineTest.class'
|
||||||
|
exclude '/org/logstash/config/ir/EventConditionTest.class'
|
||||||
exclude '/org/logstash/config/ir/compiler/OutputDelegatorTest.class'
|
exclude '/org/logstash/config/ir/compiler/OutputDelegatorTest.class'
|
||||||
exclude '/org/logstash/config/ir/compiler/JavaCodecDelegatorTest.class'
|
exclude '/org/logstash/config/ir/compiler/JavaCodecDelegatorTest.class'
|
||||||
exclude '/org/logstash/plugins/NamespacedMetricImplTest.class'
|
exclude '/org/logstash/plugins/NamespacedMetricImplTest.class'
|
||||||
|
@ -81,6 +82,7 @@ task rubyTests(type: Test) {
|
||||||
include '/org/logstash/RSpecTests.class'
|
include '/org/logstash/RSpecTests.class'
|
||||||
include '/org/logstash/config/ir/ConfigCompilerTest.class'
|
include '/org/logstash/config/ir/ConfigCompilerTest.class'
|
||||||
include '/org/logstash/config/ir/CompiledPipelineTest.class'
|
include '/org/logstash/config/ir/CompiledPipelineTest.class'
|
||||||
|
include '/org/logstash/config/ir/EventConditionTest.class'
|
||||||
include '/org/logstash/config/ir/compiler/OutputDelegatorTest.class'
|
include '/org/logstash/config/ir/compiler/OutputDelegatorTest.class'
|
||||||
include '/org/logstash/config/ir/compiler/JavaCodecDelegatorTest.class'
|
include '/org/logstash/config/ir/compiler/JavaCodecDelegatorTest.class'
|
||||||
include '/org/logstash/plugins/NamespacedMetricImplTest.class'
|
include '/org/logstash/plugins/NamespacedMetricImplTest.class'
|
||||||
|
|
|
@ -287,7 +287,7 @@ public interface EventCondition {
|
||||||
(EventValueExpression) left, (List<?>) ((ValueExpression) right).get()
|
(EventValueExpression) left, (List<?>) ((ValueExpression) right).get()
|
||||||
);
|
);
|
||||||
} else if (eAndE(in)) {
|
} else if (eAndE(in)) {
|
||||||
condition = in((EventValueExpression) right, (EventValueExpression) left);
|
condition = in((EventValueExpression) left, (EventValueExpression) right);
|
||||||
} else if (vAndV(in)) {
|
} else if (vAndV(in)) {
|
||||||
condition = in((ValueExpression) left, (ValueExpression) right);
|
condition = in((ValueExpression) left, (ValueExpression) right);
|
||||||
} else {
|
} else {
|
||||||
|
@ -571,8 +571,8 @@ public interface EventCondition {
|
||||||
if (lfound instanceof ConvertedList || lfound instanceof ConvertedMap) {
|
if (lfound instanceof ConvertedList || lfound instanceof ConvertedMap) {
|
||||||
return false;
|
return false;
|
||||||
} else if (lfound instanceof RubyString && rfound instanceof RubyString) {
|
} else if (lfound instanceof RubyString && rfound instanceof RubyString) {
|
||||||
return ((RubyString) lfound).getByteList()
|
return ((RubyString) rfound).getByteList()
|
||||||
.indexOf(((RubyString) rfound).getByteList()) > -1;
|
.indexOf(((RubyString) lfound).getByteList()) > -1;
|
||||||
} else if (rfound instanceof ConvertedList) {
|
} else if (rfound instanceof ConvertedList) {
|
||||||
return contains((ConvertedList) rfound, lfound);
|
return contains((ConvertedList) rfound, lfound);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -50,7 +50,7 @@ public final class CompiledPipelineTest extends RubyEnvTestCase {
|
||||||
/**
|
/**
|
||||||
* Mock filter that does not modify the batch.
|
* Mock filter that does not modify the batch.
|
||||||
*/
|
*/
|
||||||
private static final IRubyObject IDENTITY_FILTER = RubyUtil.RUBY.evalScriptlet(
|
static final IRubyObject IDENTITY_FILTER = RubyUtil.RUBY.evalScriptlet(
|
||||||
String.join(
|
String.join(
|
||||||
"\n",
|
"\n",
|
||||||
"output = Object.new",
|
"output = Object.new",
|
||||||
|
@ -64,7 +64,7 @@ public final class CompiledPipelineTest extends RubyEnvTestCase {
|
||||||
/**
|
/**
|
||||||
* Mock filter that adds the value 'bar' to the field 'foo' for every event in the batch.
|
* Mock filter that adds the value 'bar' to the field 'foo' for every event in the batch.
|
||||||
*/
|
*/
|
||||||
private static final IRubyObject ADD_FIELD_FILTER = RubyUtil.RUBY.evalScriptlet(
|
static final IRubyObject ADD_FIELD_FILTER = RubyUtil.RUBY.evalScriptlet(
|
||||||
String.join(
|
String.join(
|
||||||
"\n",
|
"\n",
|
||||||
"output = Object.new",
|
"output = Object.new",
|
||||||
|
@ -458,7 +458,7 @@ public final class CompiledPipelineTest extends RubyEnvTestCase {
|
||||||
/**
|
/**
|
||||||
* Configurable Mock {@link PluginFactory}
|
* Configurable Mock {@link PluginFactory}
|
||||||
*/
|
*/
|
||||||
private static final class MockPluginFactory implements PluginFactory {
|
static final class MockPluginFactory implements PluginFactory {
|
||||||
|
|
||||||
private final Map<String, Supplier<IRubyObject>> inputs;
|
private final Map<String, Supplier<IRubyObject>> inputs;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
package org.logstash.config.ir;
|
||||||
|
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.hamcrest.MatcherAssert;
|
||||||
|
import org.jruby.RubyArray;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.logstash.RubyUtil;
|
||||||
|
import org.logstash.ext.JrubyEventExtLibrary;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.LinkedTransferQueue;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static org.logstash.config.ir.CompiledPipelineTest.IDENTITY_FILTER;
|
||||||
|
import static org.logstash.ext.JrubyEventExtLibrary.RubyEvent;
|
||||||
|
|
||||||
|
public final class EventConditionTest extends RubyEnvTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Globally accessible map of test run id to a queue of {@link JrubyEventExtLibrary.RubyEvent}
|
||||||
|
* that can be used by Ruby outputs.
|
||||||
|
*/
|
||||||
|
private static final Map<Long, Collection<RubyEvent>> EVENT_SINKS =
|
||||||
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private static final AtomicLong TEST_RUN = new AtomicLong();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique identifier for this test run so that mock test outputs can correctly identify
|
||||||
|
* their event sink in {@link #EVENT_SINKS}.
|
||||||
|
*/
|
||||||
|
private long runId;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeEach() {
|
||||||
|
runId = TEST_RUN.incrementAndGet();
|
||||||
|
EVENT_SINKS.put(runId, new LinkedTransferQueue<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void afterEach() {
|
||||||
|
EVENT_SINKS.remove(runId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public void testInclusionWithFieldInField() throws Exception {
|
||||||
|
final PipelineIR pipelineIR = ConfigCompiler.configToPipelineIR(
|
||||||
|
"input {mockinput{}} filter { " +
|
||||||
|
"mockfilter {} } " +
|
||||||
|
"output { " +
|
||||||
|
" if [left] in [right] { " +
|
||||||
|
" mockoutput{}" +
|
||||||
|
" } }",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// left list values never match
|
||||||
|
RubyEvent leftIsList = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
List listValues = Arrays.asList("foo", "bar", "baz");
|
||||||
|
leftIsList.getEvent().setField("left", listValues);
|
||||||
|
leftIsList.getEvent().setField("right", listValues);
|
||||||
|
|
||||||
|
// left map values never match
|
||||||
|
RubyEvent leftIsMap = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
Map mapValues = Collections.singletonMap("foo", "bar");
|
||||||
|
leftIsMap.getEvent().setField("left", mapValues);
|
||||||
|
leftIsMap.getEvent().setField("right", mapValues);
|
||||||
|
|
||||||
|
// left and right string values match when right.contains(left)
|
||||||
|
RubyEvent leftIsString1 = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
leftIsString1.getEvent().setField("left", "foo");
|
||||||
|
leftIsString1.getEvent().setField("right", "zfooz");
|
||||||
|
RubyEvent leftIsString2 = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
leftIsString2.getEvent().setField("left", "foo");
|
||||||
|
leftIsString2.getEvent().setField("right", "zzz");
|
||||||
|
|
||||||
|
// right list value matches when right.contains(left)
|
||||||
|
RubyEvent rightIsList1 = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
rightIsList1.getEvent().setField("left", "bar");
|
||||||
|
rightIsList1.getEvent().setField("right", listValues);
|
||||||
|
RubyEvent rightIsList2 = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
rightIsList2.getEvent().setField("left", "zzz");
|
||||||
|
rightIsList2.getEvent().setField("right", listValues);
|
||||||
|
|
||||||
|
// non-string values match when left == right
|
||||||
|
RubyEvent nonStringValue1 = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
nonStringValue1.getEvent().setField("left", 42L);
|
||||||
|
nonStringValue1.getEvent().setField("right", 42L);
|
||||||
|
RubyEvent nonStringValue2 = RubyEvent.newRubyEvent(RubyUtil.RUBY);
|
||||||
|
nonStringValue2.getEvent().setField("left", 42L);
|
||||||
|
nonStringValue2.getEvent().setField("right", 43L);
|
||||||
|
|
||||||
|
RubyArray inputBatch = RubyUtil.RUBY.newArray(leftIsList, leftIsMap, leftIsString1, leftIsString2,
|
||||||
|
rightIsList1, rightIsList2, nonStringValue1, nonStringValue2);
|
||||||
|
|
||||||
|
new CompiledPipeline(
|
||||||
|
pipelineIR,
|
||||||
|
new CompiledPipelineTest.MockPluginFactory(
|
||||||
|
Collections.singletonMap("mockinput", () -> null),
|
||||||
|
Collections.singletonMap("mockfilter", () -> IDENTITY_FILTER),
|
||||||
|
Collections.singletonMap("mockoutput", mockOutputSupplier())
|
||||||
|
)
|
||||||
|
).buildExecution().compute(inputBatch, false, false);
|
||||||
|
final RubyEvent[] outputEvents = EVENT_SINKS.get(runId).toArray(new RubyEvent[0]);
|
||||||
|
|
||||||
|
MatcherAssert.assertThat(outputEvents.length, CoreMatchers.is(3));
|
||||||
|
MatcherAssert.assertThat(outputEvents[0], CoreMatchers.is(leftIsString1));
|
||||||
|
MatcherAssert.assertThat(outputEvents[1], CoreMatchers.is(rightIsList1));
|
||||||
|
MatcherAssert.assertThat(outputEvents[2], CoreMatchers.is(nonStringValue1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Supplier<Consumer<Collection<RubyEvent>>> mockOutputSupplier() {
|
||||||
|
return () -> events -> events.forEach(
|
||||||
|
event -> EVENT_SINKS.get(runId).add(event)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue