#!/usr/bin/ruby -I./lib/ -I../lib/
require 'test/unit'
require 'custodian/parser'
#
# Unit test for our parser.
#
class TestCustodianParser < Test::Unit::TestCase
#
# Create the test suite environment: NOP.
#
def setup
end
#
# Destroy the test suite environment: NOP.
#
def teardown
end
#
# Test we can create a new parser object - specifically
# that it throws exceptions if it is not given a filename
# that exists.
#
def test_init
#
# Constructor
#
assert_nothing_raised do
Custodian::Parser.new()
end
end
def test_period
parser = Custodian::Parser.new()
result = parser.parse_line( "example.vm.bytemark.co.uk must run ping except between 00-23" )
assert( result.nil? )
end
#
# Test the different kinds of parsing:
#
# 1. By string - single line.
# 2. By array - with multiple lines.
# 3. By lines - with newlines.
#
def test_parsing_api
#
# 1. By string.
#
parser = Custodian::Parser.new()
# 1.a. Comment lines return nil.
result = parser.parse_line( "# this is a comment" )
assert( result.nil? )
# 1.b. Non-strings are an error
assert_raise ArgumentError do
result = parser.parse_line( nil )
end
# 1.c. Adding a test will return an array of test-objects.
result = parser.parse_line( "smtp.bytemark.co.uk must run smtp on 25 otherwise 'failure'." );
assert( !result.nil? )
assert( result.kind_of? Array )
assert( result.size == 1 )
#
# 2. By array.
#
parser = Custodian::Parser.new()
# 2.a. Comment lines return nil.
tmp = Array.new()
tmp.push( "# This is a comment.." )
assert( parser.parse_lines( tmp ).nil? )
# 2.b. Adding a test will return an array of test-objects.
tmp = Array.new()
tmp.push( "smtp.bytemark.co.uk must run ssh on 22 otherwise 'oops'." );
ret = parser.parse_lines( tmp )
assert( ret.kind_of? Array );
assert( ret.size == 1 )
#
# 3. By lines
#
parser = Custodian::Parser.new()
# 3.a. Comment lines return nil.
str =<<EOF
# This is a comment
# This is also a fine comment
EOF
assert( parser.parse_lines( str ).nil? )
# 3.b. Adding a test will return an array of test-objects.
str = <<EOF
smtp.bytemark.co.uk must run smtp on 25.
google.com must run ping otherwise 'internet broken?'.
EOF
ret = parser.parse_lines( str )
assert( ret.kind_of? Array );
assert( ret.size == 1 )
end
#
# Test that we can define macros.
#
def test_macros_lines
parser = Custodian::Parser.new()
#
# Input text
#
text =<<EOF
FOO is kvm1.vm.bytemark.co.uk.
TEST is kvm2.vm.bytemark.co.uk.
EOF
#
# Test the parser with this text
#
parser.parse_lines( text )
#
# We should now have two macros.
#
macros = parser.macros
assert( ! macros.empty? )
assert( macros.size() == 2 )
end
#
# Test that we can define macros.
#
def test_macros_array
parser = Custodian::Parser.new()
#
# Input text
#
text = Array.new()
text.push( "FOO is kvm1.vm.bytemark.co.uk." );
text.push( "FOO2 is kvm2.vm.bytemark.co.uk." );
#
# Test the parser with this text
#
parser.parse_lines( text )
#
# We should now have two macros.
#
macros = parser.macros
assert( ! macros.empty? )
assert( macros.size() == 2 )
end
#
# Duplicate macros are a bug
#
def test_duplicate_macros
parser = Custodian::Parser.new()
#
# Input text to parse.
#
text = Array.new()
text.push( "FOO is kvm1.vm.bytemark.co.uk." );
text.push( "FOO is kvm2.vm.bytemark.co.uk." );
#
# Test the parser with this text
#
assert_raise ArgumentError do
parser.parse_lines( text )
end
#
# We should now have one macro.
#
macros = parser.macros
assert( ! macros.empty? )
assert( macros.size() == 1 )
end
#
# Test the expansion of macros.
#
def test_macro_expansion
#
# Create a parser - validate it is free of macros.
#
parser = Custodian::Parser.new()
macros = parser.macros
assert( macros.empty? )
#
# Expand a line - which should result in no change
# as the line does not involve a known-macro
#
in_txt = "example.bytemark.co.uk must run smtp."
out_txt = parser.expand_macro( in_txt )
#
# The difference is the return value will be an array
#
assert( out_txt.kind_of? Array )
assert( out_txt.size() == 1 )
assert( out_txt[0] == in_txt )
#
# Now define a macro
#
parser.parse_line( "TARGET is example1.bytemark.co.uk and example2.bytemark.co.uk." )
macros = parser.macros
assert( !macros.empty? )
#
# Now we have a two-host macro, repeat the expansion
#
ret = parser.expand_macro( "TARGET must run smtp on 25." )
#
# The result should be an array
#
assert( ret.kind_of? Array )
assert_equal( ret.size(), 2 )
assert( ret[0] =~ /example1/)
assert( ret[1] =~ /example2/)
end
#
# Test that the parser works for HTTP-redirection
#
def test_http_redirection
#
# test data
#
data = {
"http://example must run http." => true,
"http://example must run http with status 200." => true,
"http://example must run http with content 'bar'." => true,
"http://example must run http following redirects." => true,
"http://example must run http not following redirects." => false,
"http://example must run http not following redirect." => false,
}
data.each do |str,follow|
assert_nothing_raised do
#
# Create the new parser
#
obj = Custodian::TestFactory.create( str )
assert( !obj.nil? )
assert( obj.kind_of? Array )
assert( obj.size == 1 )
assert_equal( obj[0].to_s, str )
if ( follow )
assert( obj[0].follow_redirects? )
else
assert( ! obj[0].follow_redirects? )
end
end
end
end
#
# Test that the parser works for cache-busting.
#
def test_http_cache_busting
#
# test data
#
data = {
"http://example must run http." => true,
"http://example must run http with status 200." => true,
"http://example must run http with content 'bar'." => true,
"http://example must run http without cache busting." => false,
}
data.each do |str,cb|
assert_nothing_raised do
#
# Create the new parser
#
obj = Custodian::TestFactory.create( str )
assert( !obj.nil? )
assert( obj.kind_of? Array )
assert( obj.size == 1 )
assert_equal( obj[0].to_s, str )
if ( cb )
assert( obj[0].cache_busting? )
else
assert( ! obj[0].cache_busting? )
end
end
end
end
#
# Test that the text we're going to use in alerters is present.
#
def test_alert_text
#
# test data
#
data = {
"foo must run rsync." => nil,
"foo must run redis." => nil,
"foo must not run ping." => nil,
"foo must not run ssh otherwise 'fail'" => "fail",
"foo must not run ssh otherwise 'fail'." => "fail",
"foo must run redis otherwise 'memorystorage service is dead'" => "memorystorage service is dead",
"foo must run ping otherwise 'don't you love me?'" => "don"
}
#
# For each test
#
data.each do |str,fail|
assert_nothing_raised do
#
# Create the new parser
#
obj = Custodian::TestFactory.create( str )
assert( !obj.nil? )
assert( obj.kind_of? Array )
assert( obj.size == 1 )
assert_equal( obj[0].to_s, str )
if ( fail.nil? )
assert( obj[0].get_notification_text().nil? )
else
assert_equal( obj[0].get_notification_text(), fail )
end
end
end
end
end