require 'helper'
class QQWryOutputTest < Test::Unit::TestCase
def setup
Fluent::Test.setup
end
CONFIG = %[
qqwry_lookup_key host
enable_key_city qqwry_city
remove_tag_prefix input.
tag qqwry.${tag}
]
def create_driver(conf=CONFIG,tag='test')
Fluent::Test::OutputTestDriver.new(Fluent::QQWryOutput, tag).configure(conf)
end
def test_configure
assert_raise(Fluent::ConfigError) {
d = create_driver('')
}
assert_raise(Fluent::ConfigError) {
d = create_driver('enable_key_cities')
}
d = create_driver %[
enable_key_city qqwry_city
remove_tag_prefix input.
tag qqwry.${tag}
]
assert_equal 'qqwry_city', d.instance.config['enable_key_city']
# multiple key config
d = create_driver %[
qqwry_lookup_key from.ip, to.ip
enable_key_city from_city, to_city
remove_tag_prefix input.
tag qqwry.${tag}
]
assert_equal 'from_city, to_city', d.instance.config['enable_key_city']
# multiple key config (bad configure)
assert_raise(Fluent::ConfigError) {
d = create_driver %[
qqwry_lookup_key from.ip, to.ip
enable_key_city from_city
enable_key_region from_region
remove_tag_prefix input.
tag qqwry.${tag}
]
}
# invalid json structure
assert_raise(Fluent::ConfigError) {
d = create_driver %[
qqwry_lookup_key host
invalid_json {"foo" => 123}
remove_tag_prefix input.
tag qqwry.${tag}
]
}
assert_raise(Fluent::ConfigError) {
d = create_driver %[
qqwry_lookup_key host
invalid_json {"foo" : string, "bar" : 123}
remove_tag_prefix input.
tag qqwry.${tag}
]
}
end
def test_emit
d1 = create_driver(CONFIG, 'input.access')
d1.run do
d1.emit({'host' => '66.102.3.80', 'message' => 'valid ip'})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['qqwry_city']
assert_equal nil, emits[1][2]['qqwry_city']
end
def test_emit_tag_option
d1 = create_driver(%[
qqwry_lookup_key host
qqwry_city ${city['host']}
remove_tag_prefix input.
tag qqwry.${tag}
], 'input.access')
d1.run do
d1.emit({'host' => '66.102.3.80', 'message' => 'valid ip'})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['qqwry_city']
assert_equal nil, emits[1][2]['qqwry_city']
end
def test_emit_tag_parts
d1 = create_driver(%[
qqwry_lookup_key host
qqwry_city ${city['host']}
tag qqwry.${tag_parts[1]}.${tag_parts[2..3]}.${tag_parts[-1]}
], '0.1.2.3')
d1.run do
d1.emit({'host' => '66.102.3.80'})
end
emits = d1.emits
assert_equal 1, emits.length
assert_equal 'qqwry.1.2.3.3', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['qqwry_city']
end
def test_emit_nested_attr
d1 = create_driver(%[
qqwry_lookup_key host.ip
enable_key_city qqwry_city
remove_tag_prefix input.
add_tag_prefix qqwry.
], 'input.access')
d1.run do
d1.emit({'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip'})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['qqwry_city']
assert_equal nil, emits[1][2]['qqwry_city']
end
def test_emit_with_unknown_address
d1 = create_driver(CONFIG, 'input.access')
d1.run do
# 203.0.113.1 is a test address described in RFC5737
d1.emit({'host' => '203.0.113.1', 'message' => 'invalid ip'})
d1.emit({'host' => '0', 'message' => 'invalid ip'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal nil, emits[0][2]['qqwry_city']
assert_equal 'qqwry.access', emits[1][0] # tag
assert_equal nil, emits[1][2]['qqwry_city']
end
def test_emit_multiple_key
d1 = create_driver(%[
qqwry_lookup_key from.ip, to.ip
enable_key_city from_city, to_city
remove_tag_prefix input.
add_tag_prefix qqwry.
], 'input.access')
d1.run do
d1.emit({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.95.42'}})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['from_city']
assert_equal 'Musashino', emits[0][2]['to_city']
assert_equal nil, emits[1][2]['from_city']
assert_equal nil, emits[1][2]['to_city']
end
def test_emit_multiple_key_multiple_record
d1 = create_driver(%[
qqwry_lookup_key from.ip, to.ip
enable_key_city from_city, to_city
enable_key_country_name from_country, to_country
remove_tag_prefix input.
add_tag_prefix qqwry.
], 'input.access')
d1.run do
d1.emit({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.95.42'}})
d1.emit({'from' => {'ip' => '66.102.3.80'}})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 3, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['from_city']
assert_equal 'United States', emits[0][2]['from_country']
assert_equal 'Musashino', emits[0][2]['to_city']
assert_equal 'Japan', emits[0][2]['to_country']
assert_equal 'Mountain View', emits[1][2]['from_city']
assert_equal 'United States', emits[1][2]['from_country']
assert_equal nil, emits[1][2]['to_city']
assert_equal nil, emits[1][2]['to_country']
assert_equal nil, emits[2][2]['from_city']
assert_equal nil, emits[2][2]['from_country']
assert_equal nil, emits[2][2]['to_city']
assert_equal nil, emits[2][2]['to_country']
end
def test_emit_record_directive
d1 = create_driver(%[
qqwry_lookup_key from.ip
from_city ${city['from.ip']}
from_country ${country_name['from.ip']}
latitude ${latitude['from.ip']}
longitude ${longitude['from.ip']}
float_concat ${latitude['from.ip']},${longitude['from.ip']}
float_array [${longitude['from.ip']}, ${latitude['from.ip']}]
float_nest { "lat" : ${latitude['from.ip']}, "lon" : ${longitude['from.ip']}}
string_concat ${latitude['from.ip']},${longitude['from.ip']}
string_array [${city['from.ip']}, ${country_name['from.ip']}]
string_nest { "city" : ${city['from.ip']}, "country_name" : ${country_name['from.ip']}}
unknown_city ${city['unknown_key']}
undefined ${city['undefined']}
broken_array1 [${longitude['from.ip']}, ${latitude['undefined']}]
broken_array2 [${longitude['undefined']}, ${latitude['undefined']}]
remove_tag_prefix input.
tag qqwry.${tag}
], 'input.access')
d1.run do
d1.emit({'from' => {'ip' => '66.102.3.80'}})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['from_city']
assert_equal 'United States', emits[0][2]['from_country']
assert_equal 37.4192008972168, emits[0][2]['latitude']
assert_equal -122.05740356445312, emits[0][2]['longitude']
assert_equal '37.4192008972168,-122.05740356445312', emits[0][2]['float_concat']
assert_equal [-122.05740356445312, 37.4192008972168], emits[0][2]['float_array']
float_nest = {"lat" => 37.4192008972168, "lon" => -122.05740356445312 }
assert_equal float_nest, emits[0][2]['float_nest']
assert_equal '37.4192008972168,-122.05740356445312', emits[0][2]['string_concat']
assert_equal ["Mountain View", "United States"], emits[0][2]['string_array']
string_nest = {"city" => "Mountain View", "country_name" => "United States"}
assert_equal string_nest, emits[0][2]['string_nest']
assert_equal nil, emits[0][2]['unknown_city']
assert_equal nil, emits[0][2]['undefined']
assert_equal [-122.05740356445312, nil], emits[0][2]['broken_array1']
assert_equal [nil, nil], emits[0][2]['broken_array2']
assert_equal nil, emits[1][2]['from_city']
assert_equal nil, emits[1][2]['from_country']
assert_equal nil, emits[1][2]['latitude']
assert_equal nil, emits[1][2]['longitude']
assert_equal ',', emits[1][2]['float_concat']
assert_equal [nil, nil], emits[1][2]['float_array']
float_nest = {"lat" => nil, "lon" => nil}
assert_equal float_nest, emits[1][2]['float_nest']
assert_equal ',', emits[1][2]['string_concat']
assert_equal [nil, nil], emits[1][2]['string_array']
string_nest = {"city" => nil, "country_name" => nil}
assert_equal string_nest, emits[1][2]['string_nest']
assert_equal nil, emits[1][2]['unknown_city']
assert_equal nil, emits[1][2]['undefined']
assert_equal [nil, nil], emits[1][2]['broken_array1']
assert_equal [nil, nil], emits[1][2]['broken_array2']
end
def test_emit_record_directive_multiple_record
d1 = create_driver(%[
qqwry_lookup_key from.ip, to.ip
from_city ${city['from.ip']}
to_city ${city['to.ip']}
from_country ${country_name['from.ip']}
to_country ${country_name['to.ip']}
string_array [${country_name['from.ip']}, ${country_name['to.ip']}]
remove_tag_prefix input.
tag qqwry.${tag}
], 'input.access')
d1.run do
d1.emit({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.95.42'}})
d1.emit({'message' => 'missing field'})
end
emits = d1.emits
assert_equal 2, emits.length
assert_equal 'qqwry.access', emits[0][0] # tag
assert_equal 'Mountain View', emits[0][2]['from_city']
assert_equal 'United States', emits[0][2]['from_country']
assert_equal 'Musashino', emits[0][2]['to_city']
assert_equal 'Japan', emits[0][2]['to_country']
assert_equal ['United States','Japan'], emits[0][2]['string_array']
assert_equal nil, emits[1][2]['from_city']
assert_equal nil, emits[1][2]['to_city']
assert_equal nil, emits[1][2]['from_country']
assert_equal nil, emits[1][2]['to_country']
assert_equal [nil, nil], emits[1][2]['string_array']
end
end