bane 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +16 -6
- data/Rakefile +1 -1
- data/TODO +5 -8
- data/bin/bane +4 -12
- data/examples/multiple_behaviors.rb +7 -6
- data/examples/readme_example.rb +2 -1
- data/examples/single_behavior.rb +2 -1
- data/lib/bane.rb +18 -5
- data/lib/bane/arguments_parser.rb +73 -0
- data/lib/bane/behavior_maker.rb +39 -0
- data/lib/bane/behaviors/responders/close_after_pause.rb +21 -0
- data/lib/bane/behaviors/responders/close_immediately.rb +14 -0
- data/lib/bane/behaviors/responders/deluge_response.rb +27 -0
- data/lib/bane/behaviors/responders/echo_response.rb +16 -0
- data/lib/bane/behaviors/responders/exported.rb +9 -0
- data/lib/bane/behaviors/responders/fixed_response.rb +25 -0
- data/lib/bane/behaviors/responders/for_each_line.rb +18 -0
- data/lib/bane/behaviors/responders/http_refuse_all_credentials.rb +31 -0
- data/lib/bane/behaviors/responders/never_respond.rb +27 -0
- data/lib/bane/behaviors/responders/newline_response.rb +18 -0
- data/lib/bane/behaviors/responders/random_response.rb +24 -0
- data/lib/bane/behaviors/responders/slow_response.rb +32 -0
- data/lib/bane/behaviors/servers/exported.rb +18 -0
- data/lib/bane/behaviors/servers/responder_server.rb +50 -0
- data/lib/bane/behaviors/servers/timeout_in_listen_queue.rb +51 -0
- data/lib/bane/command_line_configuration.rb +22 -79
- data/lib/bane/extensions.rb +7 -0
- data/test/bane/acceptance_test.rb +65 -0
- data/test/bane/arguments_parser_test.rb +76 -0
- data/test/bane/bane_test.rb +12 -0
- data/test/bane/behaviors/responders/close_after_pause_test.rb +30 -0
- data/test/bane/behaviors/responders/close_immediately_test.rb +14 -0
- data/test/bane/behaviors/responders/deluge_response_test.rb +20 -0
- data/test/bane/behaviors/responders/echo_response_test.rb +16 -0
- data/test/bane/behaviors/responders/fixed_response_test.rb +14 -0
- data/test/bane/behaviors/responders/for_each_line_test.rb +29 -0
- data/test/bane/behaviors/responders/http_refuse_all_credentials_test.rb +18 -0
- data/test/bane/behaviors/responders/never_respond_test.rb +31 -0
- data/test/bane/behaviors/responders/newline_response_test.rb +14 -0
- data/test/bane/behaviors/responders/random_response_test.rb +15 -0
- data/test/bane/behaviors/responders/slow_response_test.rb +21 -0
- data/test/bane/behaviors/servers/responder_server_test.rb +77 -0
- data/test/bane/behaviors/servers/timeout_in_listen_queue_test.rb +23 -0
- data/test/bane/command_line_configuration_test.rb +54 -72
- data/test/bane/extensions_test.rb +17 -0
- data/test/bane/fake_connection_test.rb +1 -1
- data/test/bane/launchable_role_tests.rb +20 -0
- data/test/bane/naive_http_response_test.rb +1 -1
- data/test/test_helper.rb +42 -1
- metadata +143 -99
- data/lib/bane/behavior_server.rb +0 -47
- data/lib/bane/behaviors.rb +0 -171
- data/lib/bane/compatibility.rb +0 -36
- data/lib/bane/configuration_parser.rb +0 -89
- data/lib/bane/service_registry.rb +0 -21
- data/test/bane/behavior_server_test.rb +0 -59
- data/test/bane/behaviors_test.rb +0 -135
- data/test/bane/configuration_parser_test.rb +0 -111
- data/test/bane/integration_test.rb +0 -92
- data/test/bane/service_registry_test.rb +0 -20
data/lib/bane/compatibility.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
class String
|
2
|
-
unless "".respond_to?(:each_char)
|
3
|
-
# copied from jcode in Ruby 1.8.6
|
4
|
-
def each_char
|
5
|
-
if block_given?
|
6
|
-
scan(/./m) do |x|
|
7
|
-
yield x
|
8
|
-
end
|
9
|
-
else
|
10
|
-
scan(/./m)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
unless "".respond_to?(:lines)
|
16
|
-
require "enumerator"
|
17
|
-
|
18
|
-
alias_method :lines, :to_a
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Copied from ActiveSupport
|
23
|
-
unless :to_proc.respond_to?(:to_proc)
|
24
|
-
class Symbol
|
25
|
-
# Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
|
26
|
-
#
|
27
|
-
# # The same as people.collect { |p| p.name }
|
28
|
-
# people.collect(&:name)
|
29
|
-
#
|
30
|
-
# # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
|
31
|
-
# people.select(&:manager?).collect(&:salary)
|
32
|
-
def to_proc
|
33
|
-
Proc.new { |*args| args.shift.__send__(self, *args) }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
module Bane
|
2
|
-
|
3
|
-
class ConfigurationParser
|
4
|
-
|
5
|
-
attr_reader :configurations
|
6
|
-
|
7
|
-
def initialize(*args)
|
8
|
-
warn_about_deprecation()
|
9
|
-
@configurations = []
|
10
|
-
|
11
|
-
@configurations = case args[0]
|
12
|
-
when String, Integer
|
13
|
-
map_integer_and_behavior_arguments(*args)
|
14
|
-
when Hash
|
15
|
-
map_hash_arguments(args[0])
|
16
|
-
else
|
17
|
-
raise ConfigurationError, "Unknown configuration arguments #{args.inspect}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def warn_about_deprecation
|
22
|
-
warn "Kernel#Configuration() and ConfigurationParser are deprecated. Please directly construct an array of BehaviorServers to pass to Launcher."
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def map_integer_and_behavior_arguments(*args)
|
28
|
-
port = Integer(args.shift)
|
29
|
-
|
30
|
-
behavior_classes = args
|
31
|
-
behavior_classes = ServiceRegistry.all_servers if behavior_classes.empty?
|
32
|
-
|
33
|
-
setup_linear_ports(port, behavior_classes)
|
34
|
-
end
|
35
|
-
|
36
|
-
def setup_linear_ports(port, behavior_classes)
|
37
|
-
behavior_classes.each_with_index do |behavior, index|
|
38
|
-
@configurations << create_server(port + index, find(behavior))
|
39
|
-
end
|
40
|
-
@configurations
|
41
|
-
end
|
42
|
-
|
43
|
-
def find(behavior)
|
44
|
-
case behavior
|
45
|
-
when String
|
46
|
-
raise UnknownBehaviorError.new(behavior) unless Behaviors.const_defined?(behavior.to_sym)
|
47
|
-
Behaviors.const_get(behavior)
|
48
|
-
when Module
|
49
|
-
behavior
|
50
|
-
else
|
51
|
-
raise UnknownBehaviorError.new(behavior)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def map_hash_arguments(options)
|
56
|
-
options.each_pair do |key, value|
|
57
|
-
@configurations << extract_configuration_from(key, value)
|
58
|
-
end
|
59
|
-
@configurations
|
60
|
-
end
|
61
|
-
|
62
|
-
def extract_configuration_from(port, value)
|
63
|
-
case value
|
64
|
-
when Module
|
65
|
-
behavior = value
|
66
|
-
create_server(port, behavior)
|
67
|
-
when Hash
|
68
|
-
behavior = value.delete(:behavior)
|
69
|
-
options = value
|
70
|
-
create_server(port, behavior, options)
|
71
|
-
else
|
72
|
-
raise ConfigurationError, "Unknown configuration option: #{value.inspect}"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def create_server(port, behavior, options = {})
|
77
|
-
BehaviorServer.new(port, behavior.new(options), BehaviorServer::DEFAULT_HOST)
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
# Helper method to easily create configuration.
|
85
|
-
module Kernel
|
86
|
-
def Configuration(*args)
|
87
|
-
Bane::ConfigurationParser.new(*args).configurations
|
88
|
-
end
|
89
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Bane
|
2
|
-
|
3
|
-
module ServiceRegistry
|
4
|
-
def self.all_servers
|
5
|
-
@servers ||= []
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.all_server_names
|
9
|
-
all_servers.map(&:simple_name).sort
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.register(server)
|
13
|
-
all_servers << server unless all_servers.include?(server)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.unregister(server)
|
17
|
-
all_servers.delete server
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
|
2
|
-
require 'mocha'
|
3
|
-
|
4
|
-
class BehaviorServerTest < Test::Unit::TestCase
|
5
|
-
include Bane
|
6
|
-
|
7
|
-
IRRELEVANT_IO_STREAM = nil
|
8
|
-
IRRELEVANT_OPTIONS = {}
|
9
|
-
IRRELEVANT_HOST = "1.1.1.1"
|
10
|
-
IRRELEVANT_BEHAVIOR = nil
|
11
|
-
|
12
|
-
def test_initializes_server_on_specified_port
|
13
|
-
server = BehaviorServer.new(6000, IRRELEVANT_BEHAVIOR)
|
14
|
-
assert_equal 6000, server.port
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_initializes_server_on_specified_hostname
|
18
|
-
server = BehaviorServer.new(IRRELEVANT_PORT, IRRELEVANT_BEHAVIOR, "hostname")
|
19
|
-
assert_equal "hostname", server.host
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_delegates_serve_call_to_behavior
|
23
|
-
io = mock()
|
24
|
-
behavior = mock()
|
25
|
-
server = BehaviorServer.new(IRRELEVANT_PORT, behavior)
|
26
|
-
|
27
|
-
behavior.expects(:serve).with(io)
|
28
|
-
|
29
|
-
server.serve(io)
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_connection_log_messages_use_short_behavior_name_to_shorten_log_messages
|
33
|
-
[:connecting, :disconnecting].each do |method|
|
34
|
-
assert_log_message_uses_short_behavior_name_for(method) do |server|
|
35
|
-
server.send(method, stub_everything(:peeraddr => [127, 0, 0, 1]))
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_start_stop_log_messages_use_short_behavior_name_to_shorten_log_messages
|
41
|
-
[:starting, :stopping].each do |method|
|
42
|
-
assert_log_message_uses_short_behavior_name_for(method) do |server|
|
43
|
-
server.send(method)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def assert_log_message_uses_short_behavior_name_for(method)
|
49
|
-
logger = StringIO.new
|
50
|
-
server = BehaviorServer.new(IRRELEVANT_PORT, Bane::Behaviors::CloseImmediately.new)
|
51
|
-
server.stdlog = logger
|
52
|
-
|
53
|
-
yield server
|
54
|
-
|
55
|
-
assert_match /CloseImmediately/, logger.string, "Log for #{method} should contain class short name"
|
56
|
-
assert_no_match /Behaviors::CloseImmediately/, logger.string, "Log for #{method} should not contain expanded module name"
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
data/test/bane/behaviors_test.rb
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
|
2
|
-
require 'timeout'
|
3
|
-
require 'mocha'
|
4
|
-
|
5
|
-
class BehaviorsTest < Test::Unit::TestCase
|
6
|
-
|
7
|
-
include Bane::Behaviors
|
8
|
-
|
9
|
-
def setup
|
10
|
-
@fake_connection = FakeConnection.new
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_fixed_response_sends_the_specified_message
|
14
|
-
query_server(FixedResponse.new(:message => "Test Message"))
|
15
|
-
|
16
|
-
assert_equal "Test Message", response
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_newline_response_sends_only_a_newline_character
|
20
|
-
query_server(NewlineResponse.new)
|
21
|
-
|
22
|
-
assert_equal "\n", response
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_deluge_response_sends_one_million_bytes_by_default
|
26
|
-
query_server(DelugeResponse.new)
|
27
|
-
|
28
|
-
assert_response_length 1_000_000
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_deluge_response_accepts_length_parameter
|
32
|
-
query_server(DelugeResponse.new(:length => 1))
|
33
|
-
|
34
|
-
assert_response_length 1
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_close_immediately_sends_no_response
|
38
|
-
query_server(CloseImmediately.new)
|
39
|
-
|
40
|
-
assert_empty_response()
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_never_respond_never_sends_a_response
|
44
|
-
server = NeverRespond.new
|
45
|
-
|
46
|
-
assert_raise Timeout::Error do
|
47
|
-
Timeout::timeout(1) { query_server(server) }
|
48
|
-
end
|
49
|
-
assert_empty_response
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_close_after_pause_sleeps_30_seconds_by_default
|
53
|
-
server = CloseAfterPause.new
|
54
|
-
server.expects(:sleep).with(30)
|
55
|
-
|
56
|
-
query_server(server)
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
|
-
def test_close_after_pause_accepts_duration_parameter
|
61
|
-
server = CloseAfterPause.new(:duration => 1)
|
62
|
-
server.expects(:sleep).with(1)
|
63
|
-
|
64
|
-
query_server(server)
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_close_after_pause_sends_nothing
|
68
|
-
server = CloseAfterPause.new
|
69
|
-
server.stubs(:sleep)
|
70
|
-
|
71
|
-
query_server(server)
|
72
|
-
end
|
73
|
-
|
74
|
-
def test_slow_response_sends_a_message_slowly
|
75
|
-
message = "Hi!"
|
76
|
-
delay = 0.5
|
77
|
-
|
78
|
-
server = SlowResponse.new(:pause_duration => delay, :message => message)
|
79
|
-
server.expects(:sleep).with(delay).at_least(message.length)
|
80
|
-
|
81
|
-
query_server(server)
|
82
|
-
|
83
|
-
assert_equal message, response
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_random_response_sends_a_nonempty_response
|
87
|
-
query_server(RandomResponse.new)
|
88
|
-
|
89
|
-
assert (!response.empty?), "Should have served a nonempty response"
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_refuse_all_http_credentials_sends_401_response_code
|
93
|
-
@fake_connection.will_send("GET /some/irrelevant/path HTTP/1.1")
|
94
|
-
|
95
|
-
server = HttpRefuseAllCredentials.new
|
96
|
-
query_server(server)
|
97
|
-
|
98
|
-
assert @fake_connection.read_all_queries?, "Should have read the HTTP query before sending response"
|
99
|
-
assert_match /HTTP\/1.1 401 Unauthorized/, response, 'Should have responded with the 401 response code'
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_simple_name_strips_away_the_namespace
|
103
|
-
assert_equal "SlowResponse", Bane::Behaviors::SlowResponse.simple_name
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_for_each_line_reads_a_line_before_responding
|
107
|
-
server = Bane::Behaviors::FixedResponseForEachLine.new({:message => "Dynamic"})
|
108
|
-
|
109
|
-
@fake_connection.will_send "irrelevant\n"
|
110
|
-
|
111
|
-
query_server(server)
|
112
|
-
assert_equal "Dynamic", response
|
113
|
-
|
114
|
-
assert @fake_connection.read_all_queries?
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
def query_server(server)
|
120
|
-
server.serve(@fake_connection)
|
121
|
-
end
|
122
|
-
|
123
|
-
def response
|
124
|
-
@fake_connection.string
|
125
|
-
end
|
126
|
-
|
127
|
-
def assert_empty_response
|
128
|
-
assert_equal 0, response.length, "Should have sent nothing"
|
129
|
-
end
|
130
|
-
|
131
|
-
def assert_response_length(expected_length)
|
132
|
-
assert_equal expected_length, response.length, "Response was the wrong length"
|
133
|
-
end
|
134
|
-
|
135
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
|
2
|
-
require 'mocha'
|
3
|
-
|
4
|
-
class ConfigurationParserTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
include Bane
|
7
|
-
|
8
|
-
IRRELEVANT_BEHAVIOR = Bane::Behaviors::CloseImmediately
|
9
|
-
|
10
|
-
def setup
|
11
|
-
ConfigurationParser.any_instance.stubs(:warn_about_deprecation)
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_should_map_single_port_and_server_name
|
15
|
-
expect_server_created_with :port => 3000, :behavior => Behaviors::CloseAfterPause
|
16
|
-
|
17
|
-
ConfigurationParser.new(3000, "CloseAfterPause")
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_should_map_multiple_servers_given_one_starting_port
|
21
|
-
expect_server_created_with :port => 3000, :behavior => Behaviors::CloseImmediately
|
22
|
-
expect_server_created_with :port => 3001, :behavior => Behaviors::CloseAfterPause
|
23
|
-
|
24
|
-
ConfigurationParser.new(3000, "CloseImmediately", "CloseAfterPause")
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_should_map_string_port
|
28
|
-
expect_server_created_with :port => 3000, :behavior => IRRELEVANT_BEHAVIOR
|
29
|
-
|
30
|
-
Bane::ConfigurationParser.new("3000", IRRELEVANT_BEHAVIOR)
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_should_raise_if_unknown_server_name
|
34
|
-
assert_raises Bane::UnknownBehaviorError do
|
35
|
-
Bane::ConfigurationParser.new(IRRELEVANT_PORT, "ABehaviorThatDoesNotExist")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_should_map_server_when_given_class
|
40
|
-
expect_server_created_with :port => anything(), :behavior => Behaviors::CloseAfterPause
|
41
|
-
|
42
|
-
ConfigurationParser.new(IRRELEVANT_PORT, Behaviors::CloseAfterPause)
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_should_ask_service_registry_for_all_behaviors_if_none_specified
|
46
|
-
fake_behavior = unique_behavior
|
47
|
-
another_fake_behavior = unique_behavior
|
48
|
-
|
49
|
-
expect_server_created_with :port => anything(), :behavior => fake_behavior
|
50
|
-
expect_server_created_with :port => anything(), :behavior => another_fake_behavior
|
51
|
-
|
52
|
-
ServiceRegistry.expects(:all_servers).returns([fake_behavior, another_fake_behavior])
|
53
|
-
ConfigurationParser.new(4000)
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_should_raise_exception_if_no_arguments
|
57
|
-
assert_raises ConfigurationError do
|
58
|
-
ConfigurationParser.new
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_should_raise_exception_if_nil_port_with_behaviors
|
63
|
-
assert_raises ConfigurationError do
|
64
|
-
ConfigurationParser.new(nil, IRRELEVANT_BEHAVIOR)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_should_map_single_hash_entry_as_port_and_behavior
|
69
|
-
expect_server_created_with :port => 10256, :behavior => Behaviors::CloseAfterPause
|
70
|
-
|
71
|
-
ConfigurationParser.new(
|
72
|
-
10256 => Behaviors::CloseAfterPause
|
73
|
-
)
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_should_map_multiple_hash_entries_as_port_and_behavior
|
77
|
-
expect_server_created_with :port => 10256, :behavior => Behaviors::CloseAfterPause
|
78
|
-
expect_server_created_with :port => 6450, :behavior => Behaviors::CloseImmediately
|
79
|
-
|
80
|
-
ConfigurationParser.new(
|
81
|
-
10256 => Behaviors::CloseAfterPause,
|
82
|
-
6450 => Behaviors::CloseImmediately
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_should_map_hash_with_options
|
87
|
-
expect_server_created_with :port => 10256, :behavior => Behaviors::CloseAfterPause, :options => { :duration => 3 }
|
88
|
-
expect_server_created_with :port => 11239, :behavior => Behaviors::CloseImmediately
|
89
|
-
|
90
|
-
ConfigurationParser.new(
|
91
|
-
10256 => {:behavior => Behaviors::CloseAfterPause, :duration => 3},
|
92
|
-
11239 => Behaviors::CloseImmediately
|
93
|
-
)
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
|
98
|
-
def expect_server_created_with(arguments)
|
99
|
-
arguments = { :options => anything() }.merge(arguments)
|
100
|
-
a_behavior_instance = "an instance of #{arguments[:behavior]}.to_s"
|
101
|
-
behavior = arguments[:behavior]
|
102
|
-
behavior.expects(:new).with(arguments[:options]).returns(a_behavior_instance)
|
103
|
-
BehaviorServer.expects(:new).with(arguments[:port], a_behavior_instance, BehaviorServer::DEFAULT_HOST)
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
def unique_behavior
|
108
|
-
Class.new
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|