nerve_pharmeasy 0.7.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 (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.mailmap +2 -0
  4. data/.nerve.rc +2 -0
  5. data/.travis.yml +8 -0
  6. data/CONTRIBUTING.md +28 -0
  7. data/Gemfile +2 -0
  8. data/Gemfile.lock +75 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +116 -0
  11. data/Rakefile +7 -0
  12. data/Vagrantfile +121 -0
  13. data/bin/nerve +16 -0
  14. data/example/nerve.conf.json +54 -0
  15. data/example/nerve_services/etcd_service1.json +19 -0
  16. data/example/nerve_services/zookeeper_service1.json +18 -0
  17. data/lib/nerve/configuration_manager.rb +106 -0
  18. data/lib/nerve/log.rb +24 -0
  19. data/lib/nerve/reporter/base.rb +61 -0
  20. data/lib/nerve/reporter/etcd.rb +73 -0
  21. data/lib/nerve/reporter/zookeeper.rb +101 -0
  22. data/lib/nerve/reporter.rb +18 -0
  23. data/lib/nerve/ring_buffer.rb +30 -0
  24. data/lib/nerve/service_watcher/base.rb +65 -0
  25. data/lib/nerve/service_watcher/http.rb +70 -0
  26. data/lib/nerve/service_watcher/rabbitmq.rb +68 -0
  27. data/lib/nerve/service_watcher/tcp.rb +56 -0
  28. data/lib/nerve/service_watcher.rb +152 -0
  29. data/lib/nerve/utils.rb +17 -0
  30. data/lib/nerve/version.rb +3 -0
  31. data/lib/nerve.rb +249 -0
  32. data/nerve.conf.json +23 -0
  33. data/nerve.gemspec +33 -0
  34. data/spec/.gitkeep +0 -0
  35. data/spec/configuration_manager_spec.rb +31 -0
  36. data/spec/example_services_spec.rb +42 -0
  37. data/spec/factories/check.rb +16 -0
  38. data/spec/factories/service.rb +26 -0
  39. data/spec/lib/nerve/reporter_etcd_spec.rb +18 -0
  40. data/spec/lib/nerve/reporter_spec.rb +86 -0
  41. data/spec/lib/nerve/reporter_zookeeper_spec.rb +32 -0
  42. data/spec/lib/nerve/service_watcher_spec.rb +89 -0
  43. data/spec/lib/nerve_spec.rb +186 -0
  44. data/spec/spec_helper.rb +33 -0
  45. metadata +216 -0
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+ require 'nerve/configuration_manager'
3
+ require 'nerve/service_watcher'
4
+ require 'nerve/reporter'
5
+ require 'nerve/reporter/base'
6
+ require 'nerve'
7
+
8
+ def make_mock_service_watcher
9
+ mock_service_watcher = instance_double(Nerve::ServiceWatcher)
10
+ allow(mock_service_watcher).to receive(:start)
11
+ allow(mock_service_watcher).to receive(:stop)
12
+ allow(mock_service_watcher).to receive(:alive?).and_return(true)
13
+ allow(mock_service_watcher).to receive(:was_up).and_return(true)
14
+ mock_service_watcher
15
+ end
16
+
17
+ describe Nerve::Nerve do
18
+ let(:config_manager) { Nerve::ConfigurationManager.new() }
19
+ let(:mock_config_manager) { instance_double(Nerve::ConfigurationManager) }
20
+ let(:nerve_config) { "#{File.dirname(__FILE__)}/../../example/nerve.conf.json" }
21
+ let(:nerve_instance_id) { 'testid' }
22
+ let(:mock_service_watcher_one) { make_mock_service_watcher() }
23
+ let(:mock_service_watcher_two) { make_mock_service_watcher() }
24
+ let(:mock_reporter) { Nerve::Reporter::Base.new({}) }
25
+
26
+ describe 'check run' do
27
+ subject {
28
+ expect(config_manager).to receive(:parse_options_from_argv!).and_return({
29
+ :config => nerve_config,
30
+ :instance_id => nerve_instance_id,
31
+ :check_config => true
32
+ })
33
+ config_manager.parse_options!
34
+ Nerve::Nerve.new(config_manager)
35
+ }
36
+
37
+ it 'starts up and checks config' do
38
+ expect{subject.run}.not_to raise_error
39
+ end
40
+ end
41
+
42
+ describe 'full application run' do
43
+ before(:each) {
44
+ $EXIT = false
45
+
46
+ allow(Nerve::Reporter).to receive(:new_from_service) {
47
+ mock_reporter
48
+ }
49
+ allow(Nerve::ServiceWatcher).to receive(:new) { |config|
50
+ if config['name'] == 'service1'
51
+ mock_service_watcher_one
52
+ else
53
+ mock_service_watcher_two
54
+ end
55
+ }
56
+
57
+ allow(mock_config_manager).to receive(:reload!) { }
58
+ allow(mock_config_manager).to receive(:config) { {
59
+ 'instance_id' => nerve_instance_id,
60
+ 'services' => {
61
+ 'service1' => {
62
+ 'host' => 'localhost',
63
+ 'port' => 1234
64
+ },
65
+ 'service2' => {
66
+ 'host' => 'localhost',
67
+ 'port' => 1235
68
+ },
69
+ }
70
+ } }
71
+ allow(mock_config_manager).to receive(:options) { {
72
+ :config => 'noop',
73
+ :instance_id => nerve_instance_id,
74
+ :check_config => false
75
+ } }
76
+
77
+ }
78
+
79
+ it 'does a regular run and finishes' do
80
+ nerve = Nerve::Nerve.new(mock_config_manager)
81
+
82
+ expect(nerve).to receive(:heartbeat) {
83
+ $EXIT = true
84
+ }
85
+
86
+ expect{ nerve.run }.not_to raise_error
87
+ end
88
+
89
+ it 'relaunches dead watchers' do
90
+ nerve = Nerve::Nerve.new(mock_config_manager)
91
+
92
+ iterations = 2
93
+
94
+ # One service will fail an alive? call and need to be respawned
95
+ expect(nerve).to receive(:launch_watcher).twice.with('service1', anything).and_call_original
96
+ expect(nerve).to receive(:reap_watcher).twice.with('service1').and_call_original
97
+ expect(nerve).to receive(:launch_watcher).once.with('service2', anything).and_call_original
98
+ expect(nerve).to receive(:reap_watcher).once.with('service2').and_call_original
99
+
100
+ expect(nerve).to receive(:heartbeat).exactly(iterations + 1).times do
101
+ if iterations == 2
102
+ expect(mock_service_watcher_one).to receive(:alive?).and_return(false)
103
+ nerve.instance_variable_set(:@config_to_load, true)
104
+ elsif iterations == 1
105
+ expect(mock_service_watcher_one).to receive(:alive?).and_return(true)
106
+ nerve.instance_variable_set(:@config_to_load, true)
107
+ else
108
+ $EXIT = true
109
+ end
110
+ iterations -= 1
111
+ end
112
+
113
+ expect{ nerve.run }.not_to raise_error
114
+ end
115
+
116
+ it 'responds to changes in configuration' do
117
+ nerve = Nerve::Nerve.new(mock_config_manager)
118
+
119
+ iterations = 4
120
+ expect(nerve).to receive(:heartbeat).exactly(iterations + 1).times do
121
+ if iterations == 4
122
+ expect(nerve.instance_variable_get(:@watchers).keys).to contain_exactly('service1', 'service2')
123
+
124
+ # Remove service2 from the config
125
+ expect(mock_config_manager).to receive(:config).and_return({
126
+ 'instance_id' => nerve_instance_id,
127
+ 'services' => {
128
+ 'service1' => {
129
+ 'host' => 'localhost',
130
+ 'port' => 1234
131
+ },
132
+ }
133
+ })
134
+ nerve.instance_variable_set(:@config_to_load, true)
135
+ elsif iterations == 3
136
+ expect(nerve.instance_variable_get(:@watchers).keys).to contain_exactly('service1')
137
+ expect(nerve.instance_variable_get(:@config_to_load)).to eq(false)
138
+
139
+ # Change the configuration of service1
140
+ expect(mock_config_manager).to receive(:config).and_return({
141
+ 'instance_id' => nerve_instance_id,
142
+ 'services' => {
143
+ 'service1' => {
144
+ 'host' => 'localhost',
145
+ 'port' => 1236
146
+ },
147
+ }
148
+ })
149
+ nerve.instance_variable_set(:@config_to_load, true)
150
+ elsif iterations == 2
151
+ expect(nerve.instance_variable_get(:@watchers).keys).to contain_exactly('service1')
152
+ expect(nerve.instance_variable_get(:@watchers_desired).keys).to contain_exactly('service1')
153
+ expect(nerve.instance_variable_get(:@watchers_desired)['service1']['port']).to eq(1236)
154
+ expect(nerve.instance_variable_get(:@config_to_load)).to eq(false)
155
+
156
+ # Add another service
157
+ expect(mock_config_manager).to receive(:config) { {
158
+ 'instance_id' => nerve_instance_id,
159
+ 'services' => {
160
+ 'service1' => {
161
+ 'host' => 'localhost',
162
+ 'port' => 1236
163
+ },
164
+ 'service4' => {
165
+ 'host' => 'localhost',
166
+ 'port' => 1235
167
+ },
168
+ }
169
+ } }
170
+
171
+ nerve.instance_variable_set(:@config_to_load, true)
172
+ elsif iterations == 1
173
+ expect(nerve.instance_variable_get(:@watchers).keys).to contain_exactly('service1', 'service4')
174
+ nerve.instance_variable_set(:@config_to_load, true)
175
+ else
176
+ $EXIT = true
177
+ end
178
+ iterations -= 1
179
+ end
180
+
181
+ expect{ nerve.run }.not_to raise_error
182
+ end
183
+
184
+ end
185
+ end
186
+
@@ -0,0 +1,33 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require "#{File.dirname(__FILE__)}/../lib/nerve"
8
+
9
+ require 'factory_girl'
10
+
11
+ FactoryGirl.find_definitions
12
+
13
+ RSpec.configure do |config|
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ config.include RbConfig
17
+ config.color = true
18
+
19
+ # verify every double we can think of
20
+ config.mock_with :rspec do |mocks|
21
+ mocks.verify_doubled_constant_names = true
22
+ mocks.verify_partial_doubles = true
23
+ end
24
+
25
+ # include factory-girl when running tests
26
+ config.include FactoryGirl::Syntax::Methods
27
+
28
+ # Run specs in random order to surface order dependencies. If you find an
29
+ # order dependency and want to debug it, you can fix the order by providing
30
+ # the seed, which is printed after each run.
31
+ # --seed 1234
32
+ config.order = 'random'
33
+ end
metadata ADDED
@@ -0,0 +1,216 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nerve_pharmeasy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Rhoads
8
+ - Igor Serebryany
9
+ - Pierre Carrier
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2016-08-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: zk
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: 1.9.2
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: 1.9.2
43
+ - !ruby/object:Gem::Dependency
44
+ name: bunny
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '='
48
+ - !ruby/object:Gem::Version
49
+ version: 1.1.0
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '='
55
+ - !ruby/object:Gem::Version
56
+ version: 1.1.0
57
+ - !ruby/object:Gem::Dependency
58
+ name: etcd
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: 0.2.3
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: 0.2.3
71
+ - !ruby/object:Gem::Dependency
72
+ name: rake
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: rspec
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: 3.1.0
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
98
+ version: 3.1.0
99
+ - !ruby/object:Gem::Dependency
100
+ name: factory_girl
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: pry
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ description: Nerve is a service registration daemon. It performs health checks on
128
+ your service and then publishes success or failure into one of several registries
129
+ (currently, zookeeper or etcd). Nerve is half or SmartStack, and is designed to
130
+ be operated along with Synapse to provide a full service discovery framework
131
+ email:
132
+ - martin.rhoads@airbnb.com
133
+ - igor.serebryany@airbnb.com
134
+ executables:
135
+ - nerve
136
+ extensions: []
137
+ extra_rdoc_files: []
138
+ files:
139
+ - ".gitignore"
140
+ - ".mailmap"
141
+ - ".nerve.rc"
142
+ - ".travis.yml"
143
+ - CONTRIBUTING.md
144
+ - Gemfile
145
+ - Gemfile.lock
146
+ - LICENSE.txt
147
+ - README.md
148
+ - Rakefile
149
+ - Vagrantfile
150
+ - bin/nerve
151
+ - example/nerve.conf.json
152
+ - example/nerve_services/etcd_service1.json
153
+ - example/nerve_services/zookeeper_service1.json
154
+ - lib/nerve.rb
155
+ - lib/nerve/configuration_manager.rb
156
+ - lib/nerve/log.rb
157
+ - lib/nerve/reporter.rb
158
+ - lib/nerve/reporter/base.rb
159
+ - lib/nerve/reporter/etcd.rb
160
+ - lib/nerve/reporter/zookeeper.rb
161
+ - lib/nerve/ring_buffer.rb
162
+ - lib/nerve/service_watcher.rb
163
+ - lib/nerve/service_watcher/base.rb
164
+ - lib/nerve/service_watcher/http.rb
165
+ - lib/nerve/service_watcher/rabbitmq.rb
166
+ - lib/nerve/service_watcher/tcp.rb
167
+ - lib/nerve/utils.rb
168
+ - lib/nerve/version.rb
169
+ - nerve.conf.json
170
+ - nerve.gemspec
171
+ - spec/.gitkeep
172
+ - spec/configuration_manager_spec.rb
173
+ - spec/example_services_spec.rb
174
+ - spec/factories/check.rb
175
+ - spec/factories/service.rb
176
+ - spec/lib/nerve/reporter_etcd_spec.rb
177
+ - spec/lib/nerve/reporter_spec.rb
178
+ - spec/lib/nerve/reporter_zookeeper_spec.rb
179
+ - spec/lib/nerve/service_watcher_spec.rb
180
+ - spec/lib/nerve_spec.rb
181
+ - spec/spec_helper.rb
182
+ homepage: https://github.com/airbnb/nerve
183
+ licenses: []
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 2.5.1
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: A service registration daemon
205
+ test_files:
206
+ - spec/.gitkeep
207
+ - spec/configuration_manager_spec.rb
208
+ - spec/example_services_spec.rb
209
+ - spec/factories/check.rb
210
+ - spec/factories/service.rb
211
+ - spec/lib/nerve/reporter_etcd_spec.rb
212
+ - spec/lib/nerve/reporter_spec.rb
213
+ - spec/lib/nerve/reporter_zookeeper_spec.rb
214
+ - spec/lib/nerve/service_watcher_spec.rb
215
+ - spec/lib/nerve_spec.rb
216
+ - spec/spec_helper.rb