vayacondios-client 0.2.11 → 0.3.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 (62) hide show
  1. data/.gitignore +64 -0
  2. data/.travis.yml +13 -0
  3. data/CHANGELOG.md +0 -0
  4. data/Gemfile +21 -0
  5. data/LICENSE.md +95 -0
  6. data/Procfile +2 -0
  7. data/README.md +734 -0
  8. data/Rakefile +93 -0
  9. data/bin/vcd +10 -0
  10. data/config/database.yml +6 -0
  11. data/config/spec.example.yml +18 -0
  12. data/config/vayacondios.example.yml +15 -0
  13. data/examples/configuration.rb +56 -0
  14. data/examples/event_stream.rb +19 -0
  15. data/examples/simple.rb +61 -0
  16. data/features/event.feature +319 -0
  17. data/features/events.feature +208 -0
  18. data/features/stash.feature +840 -0
  19. data/features/stashes.feature +492 -0
  20. data/features/step_definitions/stash_steps.rb +113 -0
  21. data/features/stream.feature +30 -0
  22. data/features/support/em.rb +14 -0
  23. data/features/support/env.rb +13 -0
  24. data/lib/vayacondios/client/cli.rb +456 -0
  25. data/lib/vayacondios/client/configuration.rb +13 -0
  26. data/lib/vayacondios/client/connection.rb +39 -0
  27. data/lib/vayacondios/client/http_client.rb +6 -42
  28. data/lib/vayacondios/client/http_methods.rb +85 -0
  29. data/lib/vayacondios/client.rb +21 -0
  30. data/lib/vayacondios/configuration.rb +63 -0
  31. data/lib/vayacondios-client.rb +16 -17
  32. data/lib/vayacondios.rb +22 -0
  33. data/pom.xml +168 -0
  34. data/spec/client/cli_spec.rb +283 -0
  35. data/spec/client/configuration_spec.rb +11 -0
  36. data/spec/client/http_client_spec.rb +150 -0
  37. data/spec/configuration_spec.rb +41 -0
  38. data/spec/spec_helper.rb +27 -0
  39. data/spec/support/database_helper.rb +42 -0
  40. data/spec/support/log_helper.rb +19 -0
  41. data/spec/support/shared_context_for_events.rb +22 -0
  42. data/spec/support/shared_context_for_stashes.rb +24 -0
  43. data/spec/support/shared_examples_for_handlers.rb +32 -0
  44. data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
  45. data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
  46. data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +500 -0
  47. data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
  48. data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
  49. data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
  50. data/vayacondios-client.gemspec +25 -0
  51. metadata +96 -60
  52. checksums.yaml +0 -15
  53. data/lib/vayacondios/client/config.rb +0 -7
  54. data/lib/vayacondios/client/configliere.rb +0 -38
  55. data/lib/vayacondios/client/cube_client.rb +0 -39
  56. data/lib/vayacondios/client/itemset.rb +0 -130
  57. data/lib/vayacondios/client/legacy_switch.rb +0 -43
  58. data/lib/vayacondios/client/notifier.rb +0 -123
  59. data/lib/vayacondios/client/zabbix_client.rb +0 -148
  60. data/spec/client/itemset_legacy_spec.rb +0 -55
  61. data/spec/client/itemset_spec.rb +0 -60
  62. data/spec/client/notifier_spec.rb +0 -120
@@ -1,130 +0,0 @@
1
- require 'gorillib/logger/log'
2
- require 'net/http'
3
- require 'multi_json'
4
- require_relative 'config'
5
- require_relative 'legacy_switch'
6
-
7
- class Vayacondios
8
- class Client
9
- class ItemSet
10
- def initialize host, port, organization=nil, topic=nil, id=nil
11
- @host = host
12
- @port = port
13
- @organization = organization
14
- @topic = topic
15
- @id = id
16
- end
17
-
18
- def fetch organization=nil, topic=nil, id=nil
19
- resp = execute_request(_req(:fetch, nil, organization, topic, id)) and
20
- Vayacondios.legacy_switch.extract_response(resp)
21
- end
22
-
23
- def update ary, organization=nil, topic=nil, id=nil
24
- execute_request(_req(:update, ary, organization, topic, id))
25
- end
26
-
27
- def create ary, organization=nil, topic=nil, id=nil
28
- execute_request(_req(:create, ary, organization, topic, id))
29
- end
30
-
31
- def remove ary, organization=nil, topic=nil, id=nil
32
- execute_request(_req(:remove, ary, organization, topic, id))
33
- end
34
-
35
- private
36
-
37
- def execute_request req
38
- begin
39
- resp = Net::HTTP.start(@host, @port) do |http|
40
- http.request(req)
41
- end.body
42
- result = MultiJson.decode(resp) unless resp.nil? or resp.empty?
43
- (result.respond_to?(:has_key?) and result.has_key? "error") ? nil : result
44
- rescue StandardError => ex
45
- Log.warn("problem contacting vayacondios: #{ex.message}")
46
- Log.debug(ex.backtrace.join("\n"))
47
- nil
48
- end
49
- end
50
-
51
- def path organization, topic, id
52
- if ((the_organization = (organization || @organization)).nil? ||
53
- (the_topic = (topic || @topic )).nil? ||
54
- (the_id = (id || @id )).nil?)
55
- raise ArgumentError.new("must provide organization, topic, and id!")
56
- end
57
-
58
- ['/v1', the_organization, 'itemset', the_topic, the_id].join("/")
59
- end
60
-
61
- # This is the only private method that is tested.
62
- def _req type, ary=nil, organization=nil, topic=nil, id=nil
63
-
64
- the_path = path(organization, topic, id)
65
- headers = {"content-type" => "application/json"}
66
- headers.merge!("x-method" => "PATCH") if type == :update
67
-
68
- case type
69
- when :fetch then Net::HTTP::Get
70
- when :create then Net::HTTP::Put
71
- when :update then Net::HTTP::Put
72
- when :remove then Net::HTTP::Delete
73
- else raise ArgumentError.new("invalid type: #{type}")
74
- end.new(the_path, headers).tap do |req|
75
- unless type == :fetch
76
- req.body =
77
- MultiJson.encode(Vayacondios.legacy_switch.wrap_contents(ary))
78
- end
79
- end
80
- end
81
- end
82
-
83
- # Subclasses should implement the remove_items(arr) and
84
- # add_items(arr) methods, both of which will be called with arrays
85
- # when the items in an itemset change. The run method polls the
86
- # provided itemset at a specified interval and calls these methods
87
- # appropriately.
88
- class ItemSetListener
89
- POLL_WAIT_SEC=2
90
-
91
- def initialize itemset, poll_wait_sec = POLL_WAIT_SEC
92
- @itemset = itemset
93
- @items = []
94
- @poll_wait_sec = poll_wait_sec
95
- end
96
-
97
- def run
98
- setup
99
- loop do
100
- new_items = @itemset.fetch || []
101
-
102
- Log.debug "currently configured: #{@items.inspect}"
103
- Log.debug "new items: #{new_items.inspect}"
104
-
105
- add_items(new_items - @items)
106
- remove_items(@items - new_items)
107
-
108
- @items = new_items
109
-
110
- sleep @poll_wait_sec
111
- end
112
- teardown
113
- end
114
-
115
- protected
116
-
117
- def add_items
118
- raise NoMethodError.new("class #{self.class.name} must override add_items")
119
- end
120
-
121
- def remove_items
122
- raise NoMethodError.new("class #{self.class.name} must override remove_items")
123
- end
124
-
125
- def setup() end
126
- def teardown() end
127
-
128
- end
129
- end
130
- end
@@ -1,43 +0,0 @@
1
- require 'gorillib/logger/log'
2
-
3
- class Vayacondios
4
- # Are we operating on JSON Hashes (Vayacondios) or on JSON arrays
5
- # (Vayacondios Legacy)? These classes determine which to use.
6
-
7
- class StandardContentsHandler
8
- def wrap_contents(contents) {contents: contents} end
9
- def extract_contents(document) document['contents'] end
10
- def extract_response(document) document['contents'] end
11
- def proper_request(document) true end
12
- end
13
-
14
- class LegacyContentsHandler
15
- def wrap_contents(contents) contents end
16
- def extract_contents(document) document end
17
- def extract_response(document) document end
18
- def proper_request(document) true end
19
- end
20
-
21
- @@legacy_switch = nil
22
-
23
- def self.legacy_switch
24
- if @@legacy_switch.nil?
25
- legacy_mode_on = Settings[:vayacondios][:legacy]
26
- @@legacy_switch = get_legacy_switch(legacy_mode_on)
27
- Log.info("using #{legacy_mode_on ? 'legacy' : 'standard'} mode")
28
- end
29
- @@legacy_switch
30
- end
31
-
32
- def self.force_legacy_mode on
33
- Log.info("forcing #{on ? 'legacy' : 'standard'} mode")
34
- @@legacy_switch = get_legacy_switch on
35
- end
36
-
37
- private
38
-
39
- def self.get_legacy_switch on
40
- (on ? LegacyContentsHandler : StandardContentsHandler).new
41
- end
42
- end
43
-
@@ -1,123 +0,0 @@
1
- class Vayacondios
2
-
3
- class_attribute :notifier
4
-
5
- class Notifier < Vayacondios
6
- attr_accessor :client
7
-
8
- def prepare(obj)
9
- case
10
- when obj.respond_to?(:to_inspectable) then obj.to_inspectable
11
- when obj.respond_to?(:to_wire) then obj.to_wire
12
- when obj.respond_to?(:to_hash) then obj.to_hash
13
- else
14
- raise ArgumentError.new("Cannot notify '#{obj.inspect}' -- require a hash-like object.")
15
- end
16
- end
17
-
18
- def notify(topic, cargo = {})
19
- NoMethodError.unimplemented_method(self)
20
- end
21
- end
22
-
23
- class NullNotifier < Notifier
24
- def initialize(*args) ; end
25
-
26
- def notify topic, cargo={}
27
- end
28
- end
29
-
30
- class LogNotifier < Notifier
31
-
32
- def initialize(options = {})
33
- @client = options[:log] || Log
34
- end
35
-
36
- def notify(topic, cargo = {})
37
- prepped = prepare(cargo)
38
- level = prepped.delete(:level) || :info
39
- message = "Notification: #{topic.inspect}."
40
- message += " Reason: #{prepped.delete(:reason)}." if prepped[:reason]
41
- message += " Cargo: #{prepped.inspect}"
42
- client.send(level, message)
43
- end
44
- end
45
-
46
- class HttpNotifier < Notifier
47
-
48
- def initialize(options = {})
49
- @client = Vayacondios::HttpClient.receive(options)
50
- end
51
-
52
- def notify(topic, cargo = {})
53
- prepped = prepare(cargo)
54
- client.insert(prepped, :event, topic)
55
- nil
56
- end
57
- end
58
-
59
- class CubeNotifier < Notifier
60
- def initialize(options={})
61
- @client = Vayacondios::CubeClient.receive(options)
62
- end
63
- def notify topic, cargo={}
64
- prepped = prepare(cargo)
65
- client.event(topic, prepped)
66
- nil
67
- end
68
- end
69
-
70
- class ZabbixNotifier < Notifier
71
- def initialize options={}
72
- @client = Vayacondios::ZabbixClient.receive(options)
73
- end
74
- def notify(topic, cargo={})
75
- prepped = prepare(cargo)
76
- client.insert(topic, prepped)
77
- end
78
- end
79
-
80
- class NotifierFactory
81
- def self.receive(attrs = {})
82
- type = attrs[:type]
83
- case type
84
- when 'http' then HttpNotifier.new(attrs)
85
- when 'cube' then CubeNotifier.new(attrs)
86
- when 'zabbix' then ZabbixNotifier.new(attrs)
87
- when 'log' then LogNotifier.new(attrs)
88
- when 'none','null' then NullNotifier.new(attrs)
89
- else
90
- raise ArgumentError, "<#{type}> is not a valid build option"
91
- end
92
- end
93
- end
94
-
95
- def self.default_notifier(log = nil) NotifierFactory.receive(type: 'log', log: log) ; end
96
-
97
- module Notifications
98
-
99
- def notify(topic, cargo = {})
100
- notifier.notify(topic, cargo)
101
- end
102
-
103
- def self.included klass
104
- if klass.ancestors.include? Gorillib::Model
105
- klass.class_eval do
106
- field :notifier, Vayacondios::NotifierFactory, default: Vayacondios.default_notifier, :doc => "Notifier used to notify out of band data"
107
-
108
- def receive_notifier params
109
- params.merge!(log: try(:log)) if params[:type] == 'log'
110
- @notifier = Vayacondios::NotifierFactory.receive(params)
111
- end
112
- end
113
- else
114
- klass.class_attribute :notifier
115
- klass.notifier = Vayacondios.default_notifier try(:log)
116
- end
117
- end
118
-
119
- end
120
-
121
- extend Notifications
122
- self.notifier = default_notifier
123
- end
@@ -1,148 +0,0 @@
1
- require 'socket'
2
-
3
- class Vayacondios
4
-
5
- # Used for sending events to a Zabbix server.
6
- #
7
- # An 'event' from Vayacondios' perspective is an arbitrary Hash.
8
- #
9
- # An 'event' from Zabbix's perspective is a tuple of values:
10
- #
11
- # * time
12
- # * host
13
- # * key
14
- # * value
15
- #
16
- # This client will accept a Vayacondios event and internally
17
- # translate it into a set of Zabbix events.
18
- #
19
- # @example A CPU monitoring notification
20
- #
21
- # notify "foo-server.example.com", cpu: {
22
- # util: {
23
- # user: 0.20,
24
- # idle: 0.70,
25
- # sys: 0.10
26
- # },
27
- # load: 1.3
28
- # }
29
- #
30
- # would get turned into the following events when written to Zabbix:
31
- #
32
- # @example The CPU monitoring notification translated to Zabbix events
33
- #
34
- # [
35
- # { host: "foo-server.example.com", key: "cpu.util.user", value: 0.20 }
36
- # { host: "foo-server.example.com", key: "cpu.util.idle", value: 0.70 },
37
- # { host: "foo-server.example.com", key: "cpu.util.sys", value: 0.10 },
38
- # { host: "foo-server.example.com", key: "cpu.load", value: 1.3 }
39
- # ]
40
- #
41
- # Zabbix will interpret the time as the time it receives each event.
42
- #
43
- # The following links provide details on the protocol used by Zabbix
44
- # to receive events:
45
- #
46
- # * https://www.zabbix.com/forum/showthread.php?t=20047&highlight=sender
47
- # * https://gist.github.com/1170577
48
- # * http://spin.atomicobject.com/2012/10/30/collecting-metrics-from-ruby-processes-using-zabbix-trappers/?utm_source=rubyflow&utm_medium=ao&utm_campaign=collecting-metrics-zabix
49
- class ZabbixClient
50
- include Gorillib::Builder
51
-
52
- attr_accessor :socket
53
-
54
- field :host, String, :default => 'localhost', :doc => "Host for the Zabbix server"
55
- field :port, Integer, :default => 10051, :doc => "Port for the Zabbix server"
56
-
57
- # Insert events to a Zabbix server.
58
- #
59
- # The `topic` will be used as the name of the Zabbix host to
60
- # associate event data to.
61
- #
62
- # As per the documentation for the [Zabbix sender
63
- # protocol](https://www.zabbix.com/wiki/doc/tech/proto/zabbixsenderprotocol),
64
- # a new TCP connection will be created for each event.
65
- #
66
- # @param [String] topic
67
- # @param [Hash] cargo
68
- # Array<Hash>] text
69
- def insert topic, cargo={}
70
- self.socket = TCPSocket.new(host, port)
71
- send_request(topic, cargo)
72
- handle_response
73
- self.socket.close
74
- end
75
-
76
- private
77
-
78
- # :nodoc
79
- def send_request topic, cargo
80
- socket.write(payload(topic, cargo))
81
- end
82
-
83
- # :nodoc
84
- def handle_response
85
- header = socket.recv(5)
86
- if header == "ZBXD\1"
87
- data_header = socket.recv(8)
88
- length = data_header[0,4].unpack("i")[0]
89
- response = MultiJson.load(socket.recv(length))
90
- puts response["info"]
91
- else
92
- puts "Invalid response: #{header}"
93
- end
94
- end
95
-
96
- # :nodoc
97
- def payload topic, cargo={}
98
- body = body_for(topic, cargo)
99
- header_for(body) + body
100
- end
101
-
102
- # :nodoc
103
- def body_for topic, cargo={}
104
- MultiJson.dump({request: "sender data", data: zabbix_events_from(topic, cargo) })
105
- end
106
-
107
- # :nodoc
108
- def header_for body
109
- length = body.bytesize
110
- "ZBXD\1".encode("ascii") + [length].pack("i") + "\x00\x00\x00\x00"
111
- end
112
-
113
- # :nodoc
114
- def zabbix_events_from topic, cargo, scope=''
115
- events = []
116
- case cargo
117
- when Hash
118
- cargo.each_pair do |key, value|
119
- events += zabbix_events_from(topic, value, new_scope(scope, key))
120
- end
121
- when Array
122
- cargo.each_with_index do |item, index|
123
- events += zabbix_events_from(topic, item, new_scope(scope, index))
124
- end
125
- else
126
- events << event_body(topic, scope, cargo)
127
- end
128
- events
129
- end
130
-
131
- # :nodoc
132
- def new_scope(current_scope, new_scope)
133
- [current_scope, new_scope].map(&:to_s).reject(&:empty?).join('.')
134
- end
135
-
136
- # :nodoc
137
- def event_body topic, scope, cargo
138
- value = case cargo
139
- when Hash then cargo[:value]
140
- when Array then cargo.first
141
- else cargo
142
- end
143
- { host: topic, key: scope, value: value }
144
- end
145
-
146
- end
147
- end
148
-
@@ -1,55 +0,0 @@
1
- require 'spec_helper'
2
- require_relative '../../lib/vayacondios/server/legacy_switch'
3
-
4
- require 'multi_json'
5
-
6
- require_relative '../../lib/vayacondios/client/itemset'
7
-
8
- describe Vayacondios::Client::ItemSet do
9
- context "after instantiation in legacy mode" do
10
- itemset = Vayacondios::Client::ItemSet.new("foohost", 9999, "fooorg", "footopic", "fooid")
11
- ary = ["foo", "bar", "baz"]
12
-
13
- # testing internals here to avoid shimming up HTTP libraries.
14
-
15
- it "generates a put request without a patch header when asked to create" do
16
- Vayacondios.force_legacy_mode true
17
-
18
- req = itemset.instance_eval{_req(:create, ary)}
19
-
20
- req.method.should eql('PUT')
21
- req.body.should eql(MultiJson.encode(ary))
22
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
23
- req.each_header.to_a.should_not include(["x_method", "PATCH"])
24
- end
25
-
26
- it "generates a put request with a patch header when asked to update" do
27
- Vayacondios.force_legacy_mode true
28
-
29
- req = itemset.instance_eval{_req(:update, ary)}
30
-
31
- req.method.should eql('PUT')
32
- req.body.should eql(MultiJson.encode(ary))
33
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
34
- req.each_header.to_a.should include(["x-method", "PATCH"])
35
- end
36
-
37
- it "generates a get request when asked to fetch" do
38
- req = itemset.instance_eval{_req(:fetch)}
39
-
40
- req.method.should eql('GET')
41
- req.body.should be_nil
42
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
43
- end
44
-
45
- it "generates a delete request when asked to remove" do
46
- Vayacondios.force_legacy_mode true
47
-
48
- req = itemset.instance_eval{_req(:remove, ary)}
49
-
50
- req.method.should eql('DELETE')
51
- req.body.should eql(MultiJson.encode(ary))
52
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
53
- end
54
- end
55
- end
@@ -1,60 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'multi_json'
4
-
5
- require_relative '../../lib/vayacondios/client/itemset'
6
-
7
- describe Vayacondios::Client::ItemSet do
8
- context "when initialized" do
9
- it "can be passed a host, port, organization, topic and id" do
10
- Vayacondios::Client::ItemSet.new("foohost", 9999, "fooorg", "footopic", "fooid")
11
- end
12
- end
13
-
14
- context "after instantiation" do
15
- itemset = Vayacondios::Client::ItemSet.new("foohost", 9999, "fooorg", "footopic", "fooid")
16
- ary = ["foo", "bar", "baz"]
17
-
18
- # testing internals here to avoid shimming up HTTP libraries.
19
-
20
- it "generates a put request without a patch header when asked to create" do
21
- Vayacondios.force_legacy_mode false
22
-
23
- req = itemset.instance_eval{_req(:create, ary)}
24
-
25
- req.method.should eql('PUT')
26
- req.body.should eql(MultiJson.encode(contents: ary))
27
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
28
- req.each_header.to_a.should_not include(["x_method", "PATCH"])
29
- end
30
-
31
- it "generates a put request with a patch header when asked to update" do
32
- Vayacondios.force_legacy_mode false
33
-
34
- req = itemset.instance_eval{_req(:update, ary)}
35
-
36
- req.method.should eql('PUT')
37
- req.body.should eql(MultiJson.encode(contents: ary))
38
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
39
- req.each_header.to_a.should include(["x-method", "PATCH"])
40
- end
41
-
42
- it "generates a get request when asked to fetch" do
43
- req = itemset.instance_eval{_req(:fetch)}
44
-
45
- req.method.should eql('GET')
46
- req.body.should be_nil
47
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
48
- end
49
-
50
- it "generates a delete request when asked to remove" do
51
- Vayacondios.force_legacy_mode false
52
-
53
- req = itemset.instance_eval{_req(:remove, ary)}
54
-
55
- req.method.should eql('DELETE')
56
- req.body.should eql(MultiJson.encode(contents: ary))
57
- req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
58
- end
59
- end
60
- end
@@ -1,120 +0,0 @@
1
- require 'vayacondios-client'
2
-
3
- require 'spec_helper'
4
-
5
- class FakeModel
6
- include Vayacondios::Notifications
7
- end
8
-
9
- describe FakeModel do
10
- context 'including', Vayacondios::Notifications do
11
-
12
- it 'defines an instance method notify()' do
13
- subject.should respond_to(:notify)
14
- end
15
-
16
- it 'adds a configurable attribute :notifier with default' do
17
- subject.notifier.should be_instance_of(Vayacondios.default_notifier.class)
18
- end
19
-
20
- end
21
- end
22
-
23
- describe Vayacondios::Notifier do
24
-
25
- shared_examples_for described_class do
26
- it{ should respond_to(:notify) }
27
- end
28
-
29
- context '.prepare' do
30
- context 'given a Hash-like object' do
31
- let(:hashlike) { double :hashlike, :to_hash => {} }
32
- it 'returns a Hash' do
33
- subject.prepare(hashlike).should be_instance_of(Hash)
34
- end
35
- end
36
-
37
- context 'given a bad argument' do
38
- let(:bad_arg) { 'shazam' }
39
- it 'raises an ArgumentError' do
40
- expect{ subject.prepare(bad_arg) }.to raise_error(ArgumentError, /Cannot notify.*#{bad_arg}.*require a hash-like object/)
41
- end
42
- end
43
- end
44
-
45
- end
46
-
47
- describe Vayacondios::HttpNotifier do
48
- it_behaves_like Vayacondios::Notifier
49
-
50
- its(:client){ should be_instance_of(Vayacondios::HttpClient) }
51
-
52
- context '#notify' do
53
- let(:test_client) { double :client }
54
- let(:topic) { 'weeeeeeeeeee' }
55
- let(:cargo) { Hash.new }
56
-
57
- before do
58
- subject.stub(:client).and_return(test_client)
59
- subject.stub(:prepare).and_return(cargo)
60
- end
61
-
62
- it 'notifies its client correctly' do
63
- test_client.should_receive(:insert).with(cargo, :event, topic)
64
- subject.notify(topic, cargo)
65
- end
66
- end
67
- end
68
-
69
- describe Vayacondios::LogNotifier do
70
- it_behaves_like Vayacondios::Notifier
71
-
72
- its(:client){ should be_instance_of(Logger) }
73
-
74
- context '#notify' do
75
- let(:test_client) { double :client }
76
- let(:topic) { 'weeeeeeeeeee' }
77
- let(:cargo) { Hash.new }
78
-
79
- before do
80
- subject.stub(:client).and_return(test_client)
81
- subject.stub(:prepare).and_return(cargo)
82
- end
83
-
84
- it 'notifies its client correctly' do
85
- test_client.should_receive(:info).with(/Notification.*#{topic}/)
86
- subject.notify(topic, cargo)
87
- end
88
- end
89
-
90
- end
91
-
92
- describe Vayacondios::NotifierFactory do
93
- context '.receive' do
94
- context 'given :http' do
95
- it 'builds a HttpNotifier' do
96
- described_class.receive(type: 'http').should be_instance_of(Vayacondios::HttpNotifier)
97
- end
98
- end
99
-
100
- context 'given :log' do
101
- it 'builds a LogNotifier' do
102
- described_class.receive(type: 'log').should be_instance_of(Vayacondios::LogNotifier)
103
- end
104
- end
105
-
106
- context 'given a bad argument' do
107
- it 'raises an ArgumentError' do
108
- expect{ described_class.receive(type: 'bad') }.to raise_error(ArgumentError, /not a valid build option/)
109
- end
110
- end
111
- end
112
- end
113
-
114
- describe Vayacondios do
115
-
116
- it 'has a class method notify()' do
117
- described_class.should respond_to(:notify)
118
- end
119
-
120
- end