bane 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|