require "test_utils"
module ConditionalFancines
def description
return example.metadata[:example_group][:description_args][0]
end
def conditional(expression, &block)
describe(expression) do
config <<-CONFIG
filter {
if #{expression} {
mutate { add_tag => "success" }
} else {
mutate { add_tag => "failure" }
}
}
CONFIG
instance_eval(&block)
end
end
end
describe "conditionals" do
extend LogStash::RSpec
extend ConditionalFancines
describe "simple" do
config <<-CONFIG
filter {
mutate { add_field => { "always" => "awesome" } }
if [foo] == "bar" {
mutate { add_field => { "hello" => "world" } }
} else if [bar] == "baz" {
mutate { add_field => { "fancy" => "pants" } }
} else {
mutate { add_field => { "free" => "hugs" } }
}
}
CONFIG
sample({"foo" => "bar"}) do
insist { subject["always"] } == "awesome"
insist { subject["hello"] } == "world"
insist { subject["fancy"] }.nil?
insist { subject["free"] }.nil?
end
sample({"notfoo" => "bar"}) do
insist { subject["always"] } == "awesome"
insist { subject["hello"] }.nil?
insist { subject["fancy"] }.nil?
insist { subject["free"] } == "hugs"
end
sample({"bar" => "baz"}) do
insist { subject["always"] } == "awesome"
insist { subject["hello"] }.nil?
insist { subject["fancy"] } == "pants"
insist { subject["free"] }.nil?
end
end
describe "nested" do
config <<-CONFIG
filter {
if [nest] == 123 {
mutate { add_field => { "always" => "awesome" } }
if [foo] == "bar" {
mutate { add_field => { "hello" => "world" } }
} else if [bar] == "baz" {
mutate { add_field => { "fancy" => "pants" } }
} else {
mutate { add_field => { "free" => "hugs" } }
}
}
}
CONFIG
sample("foo" => "bar", "nest" => 124) do
insist { subject["always"] }.nil?
insist { subject["hello"] }.nil?
insist { subject["fancy"] }.nil?
insist { subject["free"] }.nil?
end
sample("foo" => "bar", "nest" => 123) do
insist { subject["always"] } == "awesome"
insist { subject["hello"] } == "world"
insist { subject["fancy"] }.nil?
insist { subject["free"] }.nil?
end
sample("notfoo" => "bar", "nest" => 123) do
insist { subject["always"] } == "awesome"
insist { subject["hello"] }.nil?
insist { subject["fancy"] }.nil?
insist { subject["free"] } == "hugs"
end
sample("bar" => "baz", "nest" => 123) do
insist { subject["always"] } == "awesome"
insist { subject["hello"] }.nil?
insist { subject["fancy"] } == "pants"
insist { subject["free"] }.nil?
end
end
describe "comparing two fields" do
config <<-CONFIG
filter {
if [foo] == [bar] {
mutate { add_tag => woot }
}
}
CONFIG
sample("foo" => 123, "bar" => 123) do
insist { subject["tags"] }.include?("woot")
end
end
describe "the 'in' operator" do
config <<-CONFIG
filter {
if [foo] in [foobar] {
mutate { add_tag => "field in field" }
}
if [foo] in "foo" {
mutate { add_tag => "field in string" }
}
if "hello" in [greeting] {
mutate { add_tag => "string in field" }
}
if [foo] in ["hello", "world", "foo"] {
mutate { add_tag => "field in list" }
}
if [missing] in [alsomissing] {
mutate { add_tag => "shouldnotexist" }
}
if !("foo" in ["hello", "world"]) {
mutate { add_tag => "shouldexist" }
}
}
CONFIG
sample("foo" => "foo", "foobar" => "foobar", "greeting" => "hello world") do
insist { subject["tags"] }.include?("field in field")
insist { subject["tags"] }.include?("field in string")
insist { subject["tags"] }.include?("string in field")
insist { subject["tags"] }.include?("field in list")
reject { subject["tags"] }.include?("shouldnotexist")
insist { subject["tags"] }.include?("shouldexist")
end
end
describe "the 'not in' operator" do
config <<-CONFIG
filter {
if "foo" not in "baz" { mutate { add_tag => "baz" } }
if "foo" not in "foo" { mutate { add_tag => "foo" } }
if !("foo" not in "foo") { mutate { add_tag => "notfoo" } }
if "foo" not in [somelist] { mutate { add_tag => "notsomelist" } }
if "one" not in [somelist] { mutate { add_tag => "somelist" } }
if "foo" not in [alsomissing] { mutate { add_tag => "no string in missing field" } }
}
CONFIG
sample("foo" => "foo", "somelist" => [ "one", "two" ], "foobar" => "foobar", "greeting" => "hello world", "tags" => [ "fancypantsy" ]) do
# verify the original exists
insist { subject["tags"] }.include?("fancypantsy")
insist { subject["tags"] }.include?("baz")
reject { subject["tags"] }.include?("foo")
insist { subject["tags"] }.include?("notfoo")
insist { subject["tags"] }.include?("notsomelist")
reject { subject["tags"] }.include?("somelist")
insist { subject["tags"] }.include?("no string in missing field")
end
end
describe "operators" do
conditional "[message] == 'sample'" do
sample("sample") { insist { subject["tags"] }.include?("success") }
sample("different") { insist { subject["tags"] }.include?("failure") }
end
conditional "[message] != 'sample'" do
sample("sample") { insist { subject["tags"] }.include?("failure") }
sample("different") { insist { subject["tags"] }.include?("success") }
end
conditional "[message] < 'sample'" do
sample("apple") { insist { subject["tags"] }.include?("success") }
sample("zebra") { insist { subject["tags"] }.include?("failure") }
end
conditional "[message] > 'sample'" do
sample("zebra") { insist { subject["tags"] }.include?("success") }
sample("apple") { insist { subject["tags"] }.include?("failure") }
end
conditional "[message] <= 'sample'" do
sample("apple") { insist { subject["tags"] }.include?("success") }
sample("zebra") { insist { subject["tags"] }.include?("failure") }
sample("sample") { insist { subject["tags"] }.include?("success") }
end
conditional "[message] >= 'sample'" do
sample("zebra") { insist { subject["tags"] }.include?("success") }
sample("sample") { insist { subject["tags"] }.include?("success") }
sample("apple") { insist { subject["tags"] }.include?("failure") }
end
conditional "[message] =~ /sample/" do
sample("apple") { insist { subject["tags"] }.include?("failure") }
sample("sample") { insist { subject["tags"] }.include?("success") }
sample("some sample") { insist { subject["tags"] }.include?("success") }
end
conditional "[message] !~ /sample/" do
sample("apple") { insist { subject["tags"] }.include?("success") }
sample("sample") { insist { subject["tags"] }.include?("failure") }
sample("some sample") { insist { subject["tags"] }.include?("failure") }
end
end
describe "negated expressions" do
conditional "!([message] == 'sample')" do
sample("sample") { reject { subject["tags"] }.include?("success") }
sample("different") { reject { subject["tags"] }.include?("failure") }
end
conditional "!([message] != 'sample')" do
sample("sample") { reject { subject["tags"] }.include?("failure") }
sample("different") { reject { subject["tags"] }.include?("success") }
end
conditional "!([message] < 'sample')" do
sample("apple") { reject { subject["tags"] }.include?("success") }
sample("zebra") { reject { subject["tags"] }.include?("failure") }
end
conditional "!([message] > 'sample')" do
sample("zebra") { reject { subject["tags"] }.include?("success") }
sample("apple") { reject { subject["tags"] }.include?("failure") }
end
conditional "!([message] <= 'sample')" do
sample("apple") { reject { subject["tags"] }.include?("success") }
sample("zebra") { reject { subject["tags"] }.include?("failure") }
sample("sample") { reject { subject["tags"] }.include?("success") }
end
conditional "!([message] >= 'sample')" do
sample("zebra") { reject { subject["tags"] }.include?("success") }
sample("sample") { reject { subject["tags"] }.include?("success") }
sample("apple") { reject { subject["tags"] }.include?("failure") }
end
conditional "!([message] =~ /sample/)" do
sample("apple") { reject { subject["tags"] }.include?("failure") }
sample("sample") { reject { subject["tags"] }.include?("success") }
sample("some sample") { reject { subject["tags"] }.include?("success") }
end
conditional "!([message] !~ /sample/)" do
sample("apple") { reject { subject["tags"] }.include?("success") }
sample("sample") { reject { subject["tags"] }.include?("failure") }
sample("some sample") { reject { subject["tags"] }.include?("failure") }
end
end
describe "value as an expression" do
# testing that a field has a value should be true.
conditional "[message]" do
sample("apple") { insist { subject["tags"] }.include?("success") }
sample("sample") { insist { subject["tags"] }.include?("success") }
sample("some sample") { insist { subject["tags"] }.include?("success") }
end
# testing that a missing field has a value should be false.
conditional "[missing]" do
sample("apple") { insist { subject["tags"] }.include?("failure") }
sample("sample") { insist { subject["tags"] }.include?("failure") }
sample("some sample") { insist { subject["tags"] }.include?("failure") }
end
end
describe "logic operators" do
describe "and" do
conditional "[message] and [message]" do
sample("whatever") { insist { subject["tags"] }.include?("success") }
end
conditional "[message] and ![message]" do
sample("whatever") { insist { subject["tags"] }.include?("failure") }
end
conditional "![message] and [message]" do
sample("whatever") { insist { subject["tags"] }.include?("failure") }
end
conditional "![message] and ![message]" do
sample("whatever") { insist { subject["tags"] }.include?("failure") }
end
end
describe "or" do
conditional "[message] or [message]" do
sample("whatever") { insist { subject["tags"] }.include?("success") }
end
conditional "[message] or ![message]" do
sample("whatever") { insist { subject["tags"] }.include?("success") }
end
conditional "![message] or [message]" do
sample("whatever") { insist { subject["tags"] }.include?("success") }
end
conditional "![message] or ![message]" do
sample("whatever") { insist { subject["tags"] }.include?("failure") }
end
end
end
end