emque-consuming 1.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +40 -0
  3. data/.travis.yml +10 -0
  4. data/CHANGELOG.md +11 -0
  5. data/Gemfile +7 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +205 -0
  8. data/Rakefile +14 -0
  9. data/bin/emque +5 -0
  10. data/emque-consuming.gemspec +36 -0
  11. data/lib/emque/consuming/actor.rb +21 -0
  12. data/lib/emque/consuming/adapter.rb +47 -0
  13. data/lib/emque/consuming/adapters/rabbit_mq/manager.rb +111 -0
  14. data/lib/emque/consuming/adapters/rabbit_mq/retry_worker.rb +59 -0
  15. data/lib/emque/consuming/adapters/rabbit_mq/worker.rb +87 -0
  16. data/lib/emque/consuming/adapters/rabbit_mq.rb +26 -0
  17. data/lib/emque/consuming/application.rb +112 -0
  18. data/lib/emque/consuming/cli.rb +140 -0
  19. data/lib/emque/consuming/command_receivers/base.rb +37 -0
  20. data/lib/emque/consuming/command_receivers/http_server.rb +103 -0
  21. data/lib/emque/consuming/command_receivers/unix_socket.rb +169 -0
  22. data/lib/emque/consuming/configuration.rb +63 -0
  23. data/lib/emque/consuming/consumer/common.rb +61 -0
  24. data/lib/emque/consuming/consumer.rb +33 -0
  25. data/lib/emque/consuming/consuming.rb +27 -0
  26. data/lib/emque/consuming/control/errors.rb +41 -0
  27. data/lib/emque/consuming/control/workers.rb +23 -0
  28. data/lib/emque/consuming/control.rb +33 -0
  29. data/lib/emque/consuming/core.rb +89 -0
  30. data/lib/emque/consuming/error_tracker.rb +39 -0
  31. data/lib/emque/consuming/generators/application.rb +95 -0
  32. data/lib/emque/consuming/helpers.rb +29 -0
  33. data/lib/emque/consuming/logging.rb +32 -0
  34. data/lib/emque/consuming/message.rb +22 -0
  35. data/lib/emque/consuming/pidfile.rb +54 -0
  36. data/lib/emque/consuming/router.rb +73 -0
  37. data/lib/emque/consuming/runner.rb +168 -0
  38. data/lib/emque/consuming/status.rb +26 -0
  39. data/lib/emque/consuming/tasks.rb +121 -0
  40. data/lib/emque/consuming/transmitter.rb +31 -0
  41. data/lib/emque/consuming/version.rb +5 -0
  42. data/lib/emque/consuming.rb +9 -0
  43. data/lib/emque-consuming.rb +3 -0
  44. data/lib/templates/.gitignore.tt +25 -0
  45. data/lib/templates/Gemfile.tt +6 -0
  46. data/lib/templates/Rakefile.tt +7 -0
  47. data/lib/templates/config/application.rb.tt +42 -0
  48. data/lib/templates/config/environments/development.rb.tt +2 -0
  49. data/lib/templates/config/environments/production.rb.tt +2 -0
  50. data/lib/templates/config/environments/staging.rb.tt +2 -0
  51. data/lib/templates/config/environments/test.rb.tt +2 -0
  52. data/lib/templates/config/routes.rb.tt +8 -0
  53. data/spec/application_spec.rb +28 -0
  54. data/spec/cli_spec.rb +136 -0
  55. data/spec/configuration_spec.rb +47 -0
  56. data/spec/consumer_spec.rb +56 -0
  57. data/spec/control/errors_spec.rb +170 -0
  58. data/spec/control_spec.rb +15 -0
  59. data/spec/core_spec.rb +121 -0
  60. data/spec/dummy/config/application.rb +38 -0
  61. data/spec/dummy/config/environments/test.rb +0 -0
  62. data/spec/dummy/config/routes.rb +0 -0
  63. data/spec/error_tracker_spec.rb +64 -0
  64. data/spec/pidfile_spec.rb +74 -0
  65. data/spec/router_spec.rb +14 -0
  66. data/spec/runner_spec.rb +138 -0
  67. data/spec/spec_helper.rb +43 -0
  68. metadata +309 -0
@@ -0,0 +1,168 @@
1
+ require "emque/consuming/application"
2
+ require "emque/consuming/control"
3
+ require "emque/consuming/pidfile"
4
+ require "emque/consuming/status"
5
+ require "emque/consuming/command_receivers/http_server"
6
+ require "emque/consuming/command_receivers/unix_socket"
7
+ require "emque/consuming/transmitter"
8
+
9
+ module Emque
10
+ module Consuming
11
+ class Runner
12
+ include Emque::Consuming::Helpers
13
+
14
+ class << self
15
+ attr_accessor :instance
16
+ end
17
+
18
+ attr_reader :control, :pidfile, :status
19
+
20
+ def initialize(options = {})
21
+ self.control = Emque::Consuming::Control.new
22
+ self.options = options
23
+ self.receivers = []
24
+ self.status = Emque::Consuming::Status.new
25
+ apply_options
26
+ Emque::Consuming.application.initialize_logger
27
+ self.class.instance = self
28
+ self.pidfile = options.fetch(:pidfile, default_pidfile)
29
+ self.pid = Emque::Consuming::Pidfile.new(pidfile)
30
+ end
31
+
32
+ def app
33
+ super
34
+ end
35
+
36
+ def console
37
+ require "pry"
38
+ Pry.start
39
+ end
40
+
41
+ def http?
42
+ config.status == :on
43
+ end
44
+
45
+ def phased_restart
46
+ receivers.each { |r| r.stop && r.start }
47
+ end
48
+
49
+ def restart
50
+ stop && start
51
+ end
52
+
53
+ def restart_application
54
+ receivers.first.restart
55
+ end
56
+
57
+ def sock?
58
+ true
59
+ end
60
+
61
+ def start
62
+ exit_if_already_running!
63
+ daemonize! if daemonize?
64
+ write_pidfile!
65
+ @persist = Thread.new { loop { sleep 1 } }
66
+ set_process_title
67
+ setup_receivers
68
+ receivers.each(&:start)
69
+ persist.join
70
+ rescue Interrupt
71
+ stop
72
+ end
73
+
74
+ def stop(timeout: 5)
75
+ if persist
76
+ Thread.new do
77
+ sleep timeout
78
+ logger.error("Timeout Exceeded. Forcing Shutdown.")
79
+ persist.exit if persist.alive?
80
+ end
81
+ receivers.each(&:stop)
82
+ logger.info("Graceful shutdown successful.")
83
+ logger.info("#{config.app_name.capitalize} stopped.")
84
+ persist.exit if persist.alive?
85
+ else
86
+ Emque::Consuming::Transmitter.send(
87
+ :command => :stop,
88
+ :socket_path => config.socket_path
89
+ )
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ attr_accessor :options, :persist, :pid, :receivers
96
+ attr_writer :control, :pidfile, :status
97
+
98
+ def apply_options
99
+ options.each do |attr, val|
100
+ config.send("#{attr}=", val) if config.respond_to?(attr)
101
+ end
102
+ end
103
+
104
+ def config
105
+ Emque::Consuming.application.config
106
+ end
107
+
108
+ def daemonize?
109
+ options[:daemon]
110
+ end
111
+
112
+ def daemonize!
113
+ Process.daemon(true, true)
114
+
115
+ [$stdout, $stderr].each do |io|
116
+ File.open(Emque::Consuming.application.logfile, "ab") do |f|
117
+ io.reopen(f)
118
+ end
119
+ io.sync = true
120
+ end
121
+
122
+ $stdin.reopen("/dev/null")
123
+ end
124
+
125
+ def default_pidfile
126
+ File.join(
127
+ Emque::Consuming.application.root,
128
+ "tmp",
129
+ "pids",
130
+ "#{config.app_name}.pid"
131
+ )
132
+ end
133
+
134
+ def exit_if_already_running!
135
+ if pid.running?
136
+ [
137
+ "Pid file exists. Process #{pid} active.",
138
+ "Please ensure app is not running."
139
+ ].each do |msg|
140
+ logger.error(msg)
141
+ $stdout.puts(msg)
142
+ end
143
+
144
+ exit
145
+ end
146
+ end
147
+
148
+ def set_process_title
149
+ title = "#{config.app_name} [pidfile: #{pidfile}"
150
+ title << " | unix socket: #{config.socket_path}" if sock?
151
+ title << " | http://#{config.status_host}:#{config.status_port}" if http?
152
+ title << "]"
153
+ $0 = title
154
+ end
155
+
156
+ def setup_receivers
157
+ receivers << app
158
+ receivers << Emque::Consuming::CommandReceivers::UnixSocket.new if sock?
159
+ receivers << Emque::Consuming::CommandReceivers::HttpServer.new if http?
160
+ end
161
+
162
+ def write_pidfile!
163
+ pid.write
164
+ at_exit { FileUtils.rm_f(pidfile) }
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,26 @@
1
+ module Emque
2
+ module Consuming
3
+ class Status
4
+ include Emque::Consuming::Helpers
5
+
6
+ def to_hsh
7
+ {
8
+ :app => config.app_name,
9
+ :errors => {
10
+ :count => app.error_tracker.count,
11
+ :expire_after => app.error_tracker.expiration,
12
+ :limit => app.error_tracker.limit
13
+ },
14
+ :workers => {}.tap { |worker_stats|
15
+ app.manager.workers.each { |topic, workers|
16
+ worker_stats[topic] = {
17
+ :count => workers.size
18
+ }
19
+ }
20
+ }
21
+ }
22
+ end
23
+ alias :to_h :to_hsh
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,121 @@
1
+ module Emque
2
+ module Consuming
3
+ class Tasks
4
+ include Rake::DSL if defined? Rake::DSL
5
+ include Emque::Consuming::Helpers
6
+
7
+ def install_tasks
8
+ namespace :emque do
9
+ desc "Show the current configuration of a running instance " +
10
+ "(accepts SOCKET)"
11
+ task :configuration do
12
+ puts with_transmitter(:send, :configuration)
13
+ end
14
+
15
+ desc "Start a pry console"
16
+ task :console do
17
+ Emque::Consuming::Runner.new.console
18
+ end
19
+
20
+ namespace :errors do
21
+ desc "Clear all outstanding errors (accepts SOCKET)"
22
+ task :clear do
23
+ puts with_transmitter(:send, :errors, :clear)
24
+ end
25
+
26
+ desc "Change the number of seconds to SECONDS before future " +
27
+ "errors expire (accepts SOCKET)"
28
+ task :expire_after do
29
+ seconds = ENV.fetch("SECONDS", 3600)
30
+ puts with_transmitter(:send, :errors, :expire_after, seconds)
31
+ end
32
+
33
+ namespace :limit do
34
+ desc "Decrease the error limit (accepts SOCKET)"
35
+ task :down do
36
+ puts with_transmitter(:send, :errors, :down)
37
+ end
38
+
39
+ desc "Increase the error limit (accepts SOCKET)"
40
+ task :up do
41
+ puts with_transmitter(:send, :errors, :up)
42
+ end
43
+ end
44
+ end
45
+
46
+ desc "Show the available routes"
47
+ task :routes do
48
+ require "table_print"
49
+ tp(
50
+ [].tap { |routes|
51
+ mappings = router.instance_eval { @mappings }
52
+
53
+ mappings.each { |topic, maps|
54
+ maps.each { |mapping|
55
+ mapping.instance_eval { @mapping }.each { |route, method|
56
+ routes << {
57
+ :route => route,
58
+ :topic => topic,
59
+ :consumer => mapping.consumer,
60
+ :method => method,
61
+ :workers => router.workers(topic)
62
+ }
63
+ }
64
+ }
65
+ }
66
+ },
67
+ {:route => {:width => 50}},
68
+ :topic,
69
+ :consumer,
70
+ :method,
71
+ :workers
72
+ )
73
+ end
74
+
75
+ desc "Restart the workers inside a running instance " +
76
+ "(does not reload code; accepts SOCKET)"
77
+ task :restart do
78
+ with_transmitter(:send, :restart)
79
+ end
80
+
81
+ desc "Show the current status of a running instance " +
82
+ "(accepts SOCKET)"
83
+ task :status do
84
+ puts with_transmitter(:send, :status)
85
+ end
86
+
87
+ desc "Start a new instance (accepts PIDFILE, DAEMON)"
88
+ task :start do
89
+ daemon = ENV.fetch("DAEMON", false)
90
+ pidfile = ENV.fetch("PIDFILE", "tmp/pids/#{config.app_name}.pid")
91
+
92
+ Emque::Consuming::Runner.new({
93
+ :daemon => daemon,
94
+ :pidfile => pidfile
95
+ }).start
96
+ end
97
+
98
+ desc "Stop a running instance (accepts SOCKET)"
99
+ task :stop do
100
+ resp = with_transmitter(:send, :stop)
101
+ puts resp.length > 0 ? resp : "stopped"
102
+ end
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def with_transmitter(method, command, *args)
109
+ socket_path = ENV.fetch("SOCKET", config.socket_path)
110
+ require "emque/consuming/transmitter"
111
+ Emque::Consuming::Transmitter.send(
112
+ :command => command,
113
+ :socket_path => socket_path,
114
+ :args => args
115
+ )
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ Emque::Consuming::Tasks.new.install_tasks
@@ -0,0 +1,31 @@
1
+ require "fileutils"
2
+ require "socket"
3
+ require "oj"
4
+
5
+ module Emque
6
+ module Consuming
7
+ module Transmitter
8
+ def self.send(command:, socket_path: "tmp/emque.sock", args: [])
9
+ if File.exists?(socket_path)
10
+ socket = UNIXSocket.new(socket_path)
11
+ socket.send(Oj.dump({
12
+ :command => command,
13
+ :args => args
14
+ }, :mode => :compat), 0)
15
+ response = socket.recv(10000000)
16
+ socket.close
17
+ response
18
+ else
19
+ "Socket not found at #{socket_path}"
20
+ end
21
+ rescue Errno::ECONNREFUSED
22
+ FileUtils.rm_f(socket_path) if File.exists?(socket_path)
23
+ "The UNIX Socket found at #{socket_path} was dead"
24
+ end
25
+
26
+ def self.method_missing(method, *args)
27
+ send(command: method, args: args)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ module Emque
2
+ module Consuming
3
+ VERSION = "1.0.0.beta4"
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require "virtus"
2
+
3
+ module Emque
4
+ module Consuming; end
5
+ end
6
+
7
+ require "emque/consuming/version"
8
+ require "emque/consuming/consuming"
9
+ require "emque/consuming/cli"
@@ -0,0 +1,3 @@
1
+ module Emque; end
2
+
3
+ require "emque/consuming"
@@ -0,0 +1,25 @@
1
+ *.rbc
2
+ *.sassc
3
+ .sass-cache
4
+ capybara-*.html
5
+ .rspec
6
+ .rvmrc
7
+ /.bundle
8
+ /vendor/bundle
9
+ /log/*
10
+ /logs/*
11
+ /tmp/*
12
+ /db/*.sqlite3
13
+ /public/system/*
14
+ /coverage/
15
+ /spec/tmp/*
16
+ **.orig
17
+ rerun.txt
18
+ pickle-email-*.html
19
+ .project
20
+ config/initializers/secret_token.rb
21
+ config/*.yml
22
+ .ruby-version
23
+ .rbenv-version
24
+ /bin/stubs
25
+ spec/fixtures/vcr_cassettes/*
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ ruby "2.1.2"
4
+
5
+ gem "rake"
6
+ gem "emque-consuming", :git => "https://github.com/teamsnap/emque-consuming.git"
@@ -0,0 +1,7 @@
1
+ require_relative "config/application"
2
+ require "emque/consuming/tasks"
3
+
4
+ __DIR__ = File.dirname(__FILE__)
5
+ Dir.glob("#{__DIR__}/tasks/*.rake").each do |rake_file|
6
+ import rake_file
7
+ end
@@ -0,0 +1,42 @@
1
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
2
+ require "bundler/setup" if File.exists?(ENV["BUNDLE_GEMFILE"])
3
+
4
+ require "emque/consuming"
5
+
6
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
7
+
8
+ module <%= @name %>
9
+ class Application
10
+ include Emque::Consuming::Application
11
+
12
+ initialize_core!
13
+
14
+ <%=
15
+ [].tap { |options_out|
16
+ if @options.has_key?(:app_name)
17
+ options_out << "config.app_name = \"#{@options[:app_name]}\""
18
+ end
19
+ if @options.has_key?(:error_limit)
20
+ options_out << "config.error_limit = #{@options[:error_limit]}"
21
+ end
22
+ if @options.has_key?(:error_expiration)
23
+ options_out << "config.error_expiration = #{@options[:error_expiration]}"
24
+ end
25
+ options_out << "config.set_adapter(:rabbit_mq)"
26
+ if @options.has_key?(:status)
27
+ options_out << "config.status = :on"
28
+ end
29
+ if @options.has_key?(:status_host)
30
+ options_out << "config.status_host = \"#{@options[:status_host]}\""
31
+ end
32
+ if @options.has_key?(:status_port)
33
+ options_out << "config.status_port = #{@options[:status_port]}"
34
+ end
35
+ if @options.has_key?(:socket_path)
36
+ options_out << "config.socket_path = \"#{@options[:socket_path]}\""
37
+ end
38
+ }.join("\n ")
39
+ %>
40
+ end
41
+ end
42
+
@@ -0,0 +1,2 @@
1
+ <%= @name %>::Application.configure do
2
+ end
@@ -0,0 +1,2 @@
1
+ <%= @name %>::Application.configure do
2
+ end
@@ -0,0 +1,2 @@
1
+ <%= @name %>::Application.configure do
2
+ end
@@ -0,0 +1,2 @@
1
+ <%= @name %>::Application.configure do
2
+ end
@@ -0,0 +1,8 @@
1
+ <%= @name %>::Application.router.map do
2
+ # topic "samples" => SamplesConsumer[, :workers => 2] do
3
+ # map "samples.new" => "new_sample"
4
+ # ...
5
+ # end
6
+
7
+ # ...
8
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe Emque::Consuming::Application do
4
+ describe "#notice_error" do
5
+ it "does not trigger a shutdown if the limit has not been reached" do
6
+ Dummy::Application.config.error_limit = 2
7
+ app = Dummy::Application.new
8
+ Emque::Consuming::Runner.instance = double(:runner)
9
+
10
+ expect(Emque::Consuming::Runner.instance).to_not receive(:stop)
11
+
12
+ app.notice_error({ :test => "failure" })
13
+ end
14
+
15
+ it "triggers a shutdown one the error_limit is reached" do
16
+ Dummy::Application.config.error_limit = 2
17
+ app = Dummy::Application.new
18
+ Emque::Consuming::Runner.instance =
19
+ double(:runner, :status => double(:status, :to_h => {}))
20
+
21
+ expect(Emque::Consuming::Runner.instance)
22
+ .to receive(:stop).exactly(1).times
23
+
24
+ app.notice_error({ :test => "failure" })
25
+ app.notice_error({ :test => "another failure" })
26
+ end
27
+ end
28
+ end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,136 @@
1
+ require "spec_helper"
2
+
3
+ describe Emque::Consuming::Cli do
4
+ describe "starting a console" do
5
+ it "passes to console command to a new runner instance" do
6
+ runner = double(:runner, :send => true)
7
+
8
+ expect(Emque::Consuming::Runner).to receive(:new).and_return(runner)
9
+ expect(runner).to receive(:send).with(:console)
10
+
11
+ Emque::Consuming::Cli.new(["console"])
12
+ end
13
+ end
14
+
15
+ describe "starting an instance" do
16
+ it "passes the start command to a new runner instance" do
17
+ runner = double(:runner, :send => true)
18
+
19
+ expect(Emque::Consuming::Runner).to receive(:new).and_return(runner)
20
+ expect(runner).to receive(:send).with(:start)
21
+
22
+ Emque::Consuming::Cli.new(["start"])
23
+ end
24
+
25
+ it "passes valid arguments along to the new runner" do
26
+ command = ["start"]
27
+ valid_args = [
28
+ "-P", "tmp/pidfile.pid",
29
+ "-d",
30
+ "-S", "tmp/socket.sock",
31
+ "-e", "20",
32
+ "-x", "1000",
33
+ "--app-name", "testing",
34
+ "--env", "test"
35
+ ]
36
+ expected_options = {
37
+ :daemon => true,
38
+ :pidfile => "tmp/pidfile.pid",
39
+ :socket_path => "tmp/socket.sock",
40
+ :error_limit => 20,
41
+ :error_expiration => 1000,
42
+ :app_name => "testing",
43
+ :env => "test"
44
+ }
45
+ argv = valid_args + command
46
+ runner = double(:runner, :send => true)
47
+
48
+ expect(Emque::Consuming::Runner).to receive(:new)
49
+ .with(expected_options)
50
+ .and_return(runner)
51
+
52
+ Emque::Consuming::Cli.new(argv)
53
+ end
54
+
55
+ describe "with no options" do
56
+ it "passes the default options to the runner" do
57
+ expected_options = {
58
+ :daemon => false
59
+ }
60
+ runner = double(:runner, :send => true)
61
+
62
+ expect(Emque::Consuming::Runner).to receive(:new)
63
+ .with(expected_options)
64
+ .and_return(runner)
65
+
66
+ Emque::Consuming::Cli.new(["start"])
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "stopping an instance" do
72
+ it "passes the stop command to a new runner instance" do
73
+ runner = double(:runner, :send => true)
74
+
75
+ expect(Emque::Consuming::Runner).to receive(:new).and_return(runner)
76
+ expect(runner).to receive(:send).with(:stop)
77
+
78
+ Emque::Consuming::Cli.new(["stop"])
79
+ end
80
+ end
81
+
82
+ describe "creating a new application" do
83
+ it "passes the new command to a new application generator instance" do
84
+ generator = double(:generator, :generate => true)
85
+
86
+ expect(Emque::Consuming::Generators::Application).to receive(:new)
87
+ .and_return(generator)
88
+ expect(generator).to receive(:generate)
89
+
90
+ Emque::Consuming::Cli.new(["new", "testapplication"])
91
+ end
92
+
93
+ it "passes valid arguments along to the new application generator" do
94
+ application_name = "testapplication"
95
+ command = ["new", application_name]
96
+ valid_args = [
97
+ "-P", "tmp/pidfile.pid",
98
+ "-d",
99
+ "-S", "tmp/socket.sock",
100
+ "-e", "20",
101
+ "-x", "1000",
102
+ "--app-name", "testing",
103
+ "--env", "test"
104
+ ]
105
+ expected_options = {
106
+ :daemon => true,
107
+ :pidfile => "tmp/pidfile.pid",
108
+ :socket_path => "tmp/socket.sock",
109
+ :error_limit => 20,
110
+ :error_expiration => 1000,
111
+ :app_name => "testing",
112
+ :env => "test"
113
+ }
114
+ argv = valid_args + command
115
+ generator = double(:generator, :generate => true)
116
+
117
+ expect(Emque::Consuming::Generators::Application).to receive(:new)
118
+ .with(expected_options, application_name)
119
+ .and_return(generator)
120
+
121
+ Emque::Consuming::Cli.new(argv)
122
+ end
123
+
124
+ it "exits if no application name is passed" do
125
+ expect { Emque::Consuming::Cli.new(["new"]) }.to raise_error(SystemExit)
126
+ end
127
+ end
128
+
129
+ it "exits if an invalid command is passed" do
130
+ expect { Emque::Consuming::Cli.new(["invalid"]) }.to raise_error(SystemExit)
131
+ end
132
+
133
+ it "exits if help is passed as a command" do
134
+ expect { Emque::Consuming::Cli.new(["help"]) }.to raise_error(SystemExit)
135
+ end
136
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Emque::Consuming::Configuration do
4
+ describe "#log_level" do
5
+ it "defaults to Logger::INFO" do
6
+ config = Emque::Consuming::Configuration.new
7
+ expect(config.log_level).to eq(Logger::INFO)
8
+ end
9
+
10
+ it "prefers the assigned value to the default" do
11
+ config = Emque::Consuming::Configuration.new
12
+ config.log_level = Logger::DEBUG
13
+ expect(config.log_level).to eq(Logger::DEBUG)
14
+ end
15
+ end
16
+
17
+ describe "#to_hsh" do
18
+ it "returns a hash" do
19
+ config = Emque::Consuming::Configuration.new
20
+ expect(config.to_hsh).to be_a Hash
21
+ end
22
+
23
+ it "returns the value of all the accessors" do
24
+ accessors = [
25
+ :app_name, :adapter, :env, :error_handlers, :error_limit,
26
+ :error_expiration, :log_level, :status_port, :status_host, :status,
27
+ :socket_path, :shutdown_handlers
28
+ ]
29
+ config = Emque::Consuming::Configuration.new
30
+
31
+ hsh = config.to_hsh
32
+
33
+ expect(hsh.keys).to eq(accessors)
34
+ accessors.each do |key|
35
+ expect(hsh.fetch(key)).to eq(config.send(key))
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "#to_h" do
41
+ it "is an alias of to_hsh" do
42
+ config = Emque::Consuming::Configuration.new
43
+
44
+ expect(config.to_h).to eq(config.to_hsh)
45
+ end
46
+ end
47
+ end