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.
Files changed (61) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +16 -6
  3. data/Rakefile +1 -1
  4. data/TODO +5 -8
  5. data/bin/bane +4 -12
  6. data/examples/multiple_behaviors.rb +7 -6
  7. data/examples/readme_example.rb +2 -1
  8. data/examples/single_behavior.rb +2 -1
  9. data/lib/bane.rb +18 -5
  10. data/lib/bane/arguments_parser.rb +73 -0
  11. data/lib/bane/behavior_maker.rb +39 -0
  12. data/lib/bane/behaviors/responders/close_after_pause.rb +21 -0
  13. data/lib/bane/behaviors/responders/close_immediately.rb +14 -0
  14. data/lib/bane/behaviors/responders/deluge_response.rb +27 -0
  15. data/lib/bane/behaviors/responders/echo_response.rb +16 -0
  16. data/lib/bane/behaviors/responders/exported.rb +9 -0
  17. data/lib/bane/behaviors/responders/fixed_response.rb +25 -0
  18. data/lib/bane/behaviors/responders/for_each_line.rb +18 -0
  19. data/lib/bane/behaviors/responders/http_refuse_all_credentials.rb +31 -0
  20. data/lib/bane/behaviors/responders/never_respond.rb +27 -0
  21. data/lib/bane/behaviors/responders/newline_response.rb +18 -0
  22. data/lib/bane/behaviors/responders/random_response.rb +24 -0
  23. data/lib/bane/behaviors/responders/slow_response.rb +32 -0
  24. data/lib/bane/behaviors/servers/exported.rb +18 -0
  25. data/lib/bane/behaviors/servers/responder_server.rb +50 -0
  26. data/lib/bane/behaviors/servers/timeout_in_listen_queue.rb +51 -0
  27. data/lib/bane/command_line_configuration.rb +22 -79
  28. data/lib/bane/extensions.rb +7 -0
  29. data/test/bane/acceptance_test.rb +65 -0
  30. data/test/bane/arguments_parser_test.rb +76 -0
  31. data/test/bane/bane_test.rb +12 -0
  32. data/test/bane/behaviors/responders/close_after_pause_test.rb +30 -0
  33. data/test/bane/behaviors/responders/close_immediately_test.rb +14 -0
  34. data/test/bane/behaviors/responders/deluge_response_test.rb +20 -0
  35. data/test/bane/behaviors/responders/echo_response_test.rb +16 -0
  36. data/test/bane/behaviors/responders/fixed_response_test.rb +14 -0
  37. data/test/bane/behaviors/responders/for_each_line_test.rb +29 -0
  38. data/test/bane/behaviors/responders/http_refuse_all_credentials_test.rb +18 -0
  39. data/test/bane/behaviors/responders/never_respond_test.rb +31 -0
  40. data/test/bane/behaviors/responders/newline_response_test.rb +14 -0
  41. data/test/bane/behaviors/responders/random_response_test.rb +15 -0
  42. data/test/bane/behaviors/responders/slow_response_test.rb +21 -0
  43. data/test/bane/behaviors/servers/responder_server_test.rb +77 -0
  44. data/test/bane/behaviors/servers/timeout_in_listen_queue_test.rb +23 -0
  45. data/test/bane/command_line_configuration_test.rb +54 -72
  46. data/test/bane/extensions_test.rb +17 -0
  47. data/test/bane/fake_connection_test.rb +1 -1
  48. data/test/bane/launchable_role_tests.rb +20 -0
  49. data/test/bane/naive_http_response_test.rb +1 -1
  50. data/test/test_helper.rb +42 -1
  51. metadata +143 -99
  52. data/lib/bane/behavior_server.rb +0 -47
  53. data/lib/bane/behaviors.rb +0 -171
  54. data/lib/bane/compatibility.rb +0 -36
  55. data/lib/bane/configuration_parser.rb +0 -89
  56. data/lib/bane/service_registry.rb +0 -21
  57. data/test/bane/behavior_server_test.rb +0 -59
  58. data/test/bane/behaviors_test.rb +0 -135
  59. data/test/bane/configuration_parser_test.rb +0 -111
  60. data/test/bane/integration_test.rb +0 -92
  61. data/test/bane/service_registry_test.rb +0 -20
@@ -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
@@ -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