protobuf-cucumber 3.10.4

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 (204) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +70 -0
  4. data/.rubocop_todo.yml +145 -0
  5. data/.travis.yml +40 -0
  6. data/.yardopts +5 -0
  7. data/CHANGES.md +344 -0
  8. data/CONTRIBUTING.md +16 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +33 -0
  12. data/Rakefile +64 -0
  13. data/bin/protoc-gen-ruby +22 -0
  14. data/bin/rpc_server +5 -0
  15. data/install-protobuf.sh +28 -0
  16. data/lib/protobuf.rb +129 -0
  17. data/lib/protobuf/cli.rb +257 -0
  18. data/lib/protobuf/code_generator.rb +120 -0
  19. data/lib/protobuf/decoder.rb +28 -0
  20. data/lib/protobuf/deprecation.rb +117 -0
  21. data/lib/protobuf/descriptors.rb +3 -0
  22. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
  23. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -0
  24. data/lib/protobuf/encoder.rb +11 -0
  25. data/lib/protobuf/enum.rb +365 -0
  26. data/lib/protobuf/exceptions.rb +9 -0
  27. data/lib/protobuf/field.rb +74 -0
  28. data/lib/protobuf/field/base_field.rb +380 -0
  29. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  30. data/lib/protobuf/field/bool_field.rb +64 -0
  31. data/lib/protobuf/field/bytes_field.rb +78 -0
  32. data/lib/protobuf/field/double_field.rb +25 -0
  33. data/lib/protobuf/field/enum_field.rb +61 -0
  34. data/lib/protobuf/field/field_array.rb +104 -0
  35. data/lib/protobuf/field/field_hash.rb +122 -0
  36. data/lib/protobuf/field/fixed32_field.rb +25 -0
  37. data/lib/protobuf/field/fixed64_field.rb +28 -0
  38. data/lib/protobuf/field/float_field.rb +43 -0
  39. data/lib/protobuf/field/int32_field.rb +21 -0
  40. data/lib/protobuf/field/int64_field.rb +34 -0
  41. data/lib/protobuf/field/integer_field.rb +23 -0
  42. data/lib/protobuf/field/message_field.rb +51 -0
  43. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  44. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  45. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  46. data/lib/protobuf/field/sint32_field.rb +21 -0
  47. data/lib/protobuf/field/sint64_field.rb +21 -0
  48. data/lib/protobuf/field/string_field.rb +51 -0
  49. data/lib/protobuf/field/uint32_field.rb +21 -0
  50. data/lib/protobuf/field/uint64_field.rb +21 -0
  51. data/lib/protobuf/field/varint_field.rb +77 -0
  52. data/lib/protobuf/generators/base.rb +85 -0
  53. data/lib/protobuf/generators/enum_generator.rb +39 -0
  54. data/lib/protobuf/generators/extension_generator.rb +27 -0
  55. data/lib/protobuf/generators/field_generator.rb +193 -0
  56. data/lib/protobuf/generators/file_generator.rb +262 -0
  57. data/lib/protobuf/generators/group_generator.rb +122 -0
  58. data/lib/protobuf/generators/message_generator.rb +104 -0
  59. data/lib/protobuf/generators/option_generator.rb +17 -0
  60. data/lib/protobuf/generators/printable.rb +160 -0
  61. data/lib/protobuf/generators/service_generator.rb +50 -0
  62. data/lib/protobuf/lifecycle.rb +33 -0
  63. data/lib/protobuf/logging.rb +39 -0
  64. data/lib/protobuf/message.rb +260 -0
  65. data/lib/protobuf/message/fields.rb +233 -0
  66. data/lib/protobuf/message/serialization.rb +85 -0
  67. data/lib/protobuf/optionable.rb +70 -0
  68. data/lib/protobuf/rpc/buffer.rb +78 -0
  69. data/lib/protobuf/rpc/client.rb +140 -0
  70. data/lib/protobuf/rpc/connectors/base.rb +221 -0
  71. data/lib/protobuf/rpc/connectors/ping.rb +89 -0
  72. data/lib/protobuf/rpc/connectors/socket.rb +78 -0
  73. data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
  74. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
  75. data/lib/protobuf/rpc/env.rb +60 -0
  76. data/lib/protobuf/rpc/error.rb +28 -0
  77. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  78. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  79. data/lib/protobuf/rpc/middleware.rb +25 -0
  80. data/lib/protobuf/rpc/middleware/exception_handler.rb +40 -0
  81. data/lib/protobuf/rpc/middleware/logger.rb +95 -0
  82. data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
  83. data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
  84. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  85. data/lib/protobuf/rpc/rpc.pb.rb +64 -0
  86. data/lib/protobuf/rpc/rpc_method.rb +16 -0
  87. data/lib/protobuf/rpc/server.rb +39 -0
  88. data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
  89. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  90. data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
  91. data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
  92. data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
  93. data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
  94. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  95. data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
  96. data/lib/protobuf/rpc/service.rb +172 -0
  97. data/lib/protobuf/rpc/service_directory.rb +261 -0
  98. data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
  99. data/lib/protobuf/rpc/service_filters.rb +250 -0
  100. data/lib/protobuf/rpc/stat.rb +119 -0
  101. data/lib/protobuf/socket.rb +21 -0
  102. data/lib/protobuf/tasks.rb +1 -0
  103. data/lib/protobuf/tasks/compile.rake +80 -0
  104. data/lib/protobuf/varint.rb +20 -0
  105. data/lib/protobuf/varint_pure.rb +31 -0
  106. data/lib/protobuf/version.rb +3 -0
  107. data/lib/protobuf/wire_type.rb +10 -0
  108. data/lib/protobuf/zmq.rb +21 -0
  109. data/profile.html +5103 -0
  110. data/proto/dynamic_discovery.proto +44 -0
  111. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  112. data/proto/google/protobuf/descriptor.proto +779 -0
  113. data/proto/rpc.proto +69 -0
  114. data/protobuf-cucumber.gemspec +57 -0
  115. data/spec/benchmark/tasks.rb +143 -0
  116. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  117. data/spec/encoding/all_types_spec.rb +103 -0
  118. data/spec/encoding/extreme_values_spec.rb +0 -0
  119. data/spec/functional/class_inheritance_spec.rb +52 -0
  120. data/spec/functional/code_generator_spec.rb +58 -0
  121. data/spec/functional/socket_server_spec.rb +59 -0
  122. data/spec/functional/zmq_server_spec.rb +105 -0
  123. data/spec/lib/protobuf/cli_spec.rb +317 -0
  124. data/spec/lib/protobuf/code_generator_spec.rb +87 -0
  125. data/spec/lib/protobuf/enum_spec.rb +307 -0
  126. data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
  127. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  128. data/spec/lib/protobuf/field/enum_field_spec.rb +44 -0
  129. data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
  130. data/spec/lib/protobuf/field/field_hash_spec.rb +168 -0
  131. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  132. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  133. data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
  134. data/spec/lib/protobuf/field/int32_field_spec.rb +120 -0
  135. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  136. data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
  137. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  138. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  139. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  140. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  141. data/spec/lib/protobuf/field/string_field_spec.rb +79 -0
  142. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  143. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  144. data/spec/lib/protobuf/field_spec.rb +192 -0
  145. data/spec/lib/protobuf/generators/base_spec.rb +154 -0
  146. data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
  147. data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
  148. data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
  149. data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
  150. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  151. data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
  152. data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
  153. data/spec/lib/protobuf/message_spec.rb +944 -0
  154. data/spec/lib/protobuf/optionable_spec.rb +265 -0
  155. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  156. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
  157. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
  158. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
  159. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -0
  160. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  161. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  162. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  163. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +91 -0
  164. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  165. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
  166. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  167. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  168. data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
  169. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +35 -0
  170. data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
  171. data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
  172. data/spec/lib/protobuf/rpc/stat_spec.rb +101 -0
  173. data/spec/lib/protobuf/varint_spec.rb +29 -0
  174. data/spec/lib/protobuf_spec.rb +105 -0
  175. data/spec/spec_helper.rb +42 -0
  176. data/spec/support/all.rb +6 -0
  177. data/spec/support/packed_field.rb +23 -0
  178. data/spec/support/protos/all_types.data.bin +0 -0
  179. data/spec/support/protos/all_types.data.txt +119 -0
  180. data/spec/support/protos/enum.pb.rb +63 -0
  181. data/spec/support/protos/enum.proto +37 -0
  182. data/spec/support/protos/extreme_values.data.bin +0 -0
  183. data/spec/support/protos/google_unittest.bin +0 -0
  184. data/spec/support/protos/google_unittest.pb.rb +798 -0
  185. data/spec/support/protos/google_unittest.proto +884 -0
  186. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  187. data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
  188. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  189. data/spec/support/protos/google_unittest_import.pb.rb +55 -0
  190. data/spec/support/protos/google_unittest_import.proto +73 -0
  191. data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
  192. data/spec/support/protos/google_unittest_import_public.proto +41 -0
  193. data/spec/support/protos/map-test.bin +157 -0
  194. data/spec/support/protos/map-test.pb.rb +85 -0
  195. data/spec/support/protos/map-test.proto +68 -0
  196. data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
  197. data/spec/support/protos/multi_field_extensions.proto +35 -0
  198. data/spec/support/protos/resource.pb.rb +172 -0
  199. data/spec/support/protos/resource.proto +137 -0
  200. data/spec/support/resource_service.rb +23 -0
  201. data/spec/support/server.rb +65 -0
  202. data/spec/support/test_app_file.rb +2 -0
  203. data/varint_prof.rb +82 -0
  204. metadata +579 -0
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/rpc/servers/socket_runner'
3
+ require 'protobuf/socket'
4
+ require SUPPORT_PATH.join('resource_service')
5
+
6
+ RSpec.describe Protobuf::Rpc::Socket::Server do
7
+ before(:each) do
8
+ load 'protobuf/socket.rb'
9
+ end
10
+
11
+ before(:all) do
12
+ load 'protobuf/socket.rb'
13
+ Thread.abort_on_exception = true
14
+ @options = OpenStruct.new(:host => "127.0.0.1", :port => 9399, :backlog => 100, :threshold => 100)
15
+ @runner = ::Protobuf::Rpc::SocketRunner.new(@options)
16
+ @server = @runner.instance_variable_get(:@server)
17
+ @server_thread = Thread.new(@runner, &:run)
18
+ Thread.pass until @server.running?
19
+ end
20
+
21
+ after(:all) do
22
+ @server.stop
23
+ @server_thread.join
24
+ end
25
+
26
+ it "Runner provides a stop method" do
27
+ expect(@runner).to respond_to(:stop)
28
+ end
29
+
30
+ it "provides a stop method" do
31
+ expect(@server).to respond_to(:stop)
32
+ end
33
+
34
+ it "signals the Server is running" do
35
+ expect(@server).to be_running
36
+ end
37
+
38
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/rpc/servers/zmq/server'
3
+
4
+ RSpec.describe Protobuf::Rpc::Zmq::Server do
5
+ subject { described_class.new(options) }
6
+
7
+ let(:options) do
8
+ {
9
+ :host => '127.0.0.1',
10
+ :port => 9399,
11
+ :worker_port => 9400,
12
+ :workers_only => true,
13
+ }
14
+ end
15
+
16
+ before do
17
+ load 'protobuf/zmq.rb'
18
+ end
19
+
20
+ after do
21
+ subject.teardown
22
+ end
23
+
24
+ describe '.running?' do
25
+ it 'returns true if running' do
26
+ subject.instance_variable_set(:@running, true)
27
+ expect(subject.running?).to be true
28
+ end
29
+
30
+ it 'returns false if not running' do
31
+ subject.instance_variable_set(:@running, false)
32
+ expect(subject.running?).to be false
33
+ end
34
+ end
35
+
36
+ describe '.stop' do
37
+ it 'sets running to false' do
38
+ subject.instance_variable_set(:@workers, [])
39
+ subject.stop
40
+ expect(subject.instance_variable_get(:@running)).to be false
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ class UtilTest
4
+ include ::Protobuf::Rpc::Zmq::Util
5
+ end
6
+
7
+ RSpec.describe ::Protobuf::Rpc::Zmq::Util do
8
+ before(:each) do
9
+ load 'protobuf/zmq.rb'
10
+ end
11
+
12
+ subject { UtilTest.new }
13
+ describe '#zmq_error_check' do
14
+ it 'raises when the error code is less than 0' do
15
+ expect do
16
+ subject.zmq_error_check(-1, :test)
17
+ end.to raise_error(/test/)
18
+ end
19
+
20
+ it 'retrieves the error string from ZeroMQ' do
21
+ allow(ZMQ::Util).to receive(:error_string).and_return('an error from zmq')
22
+ expect do
23
+ subject.zmq_error_check(-1, :test)
24
+ end.to raise_error(RuntimeError, /an error from zmq/i)
25
+ end
26
+
27
+ it 'does nothing if the error code is > 0' do
28
+ expect do
29
+ subject.zmq_error_check(1, :test)
30
+ end.to_not raise_error
31
+ end
32
+
33
+ it 'does nothing if the error code is == 0' do
34
+ expect do
35
+ subject.zmq_error_check(0, :test)
36
+ end.to_not raise_error
37
+ end
38
+ end
39
+
40
+ describe '#log_signature' do
41
+ it 'returns the signature for the log' do
42
+ expect(subject.log_signature).to include('server', 'UtilTest')
43
+ end
44
+ end
45
+
46
+ describe '.resolve_ip' do
47
+ it 'resolves ips' do
48
+ expect(subject.resolve_ip('127.0.0.1')).to eq('127.0.0.1')
49
+ end
50
+
51
+ it 'resolves non ips' do
52
+ expect(subject.resolve_ip('localhost')).to eq('127.0.0.1')
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ::Protobuf::Rpc::Zmq::Worker do
4
+ before(:each) do
5
+ load 'protobuf/zmq.rb'
6
+
7
+ fake_socket = double
8
+ expect(fake_socket).to receive(:connect).and_return(0)
9
+ expect(fake_socket).to receive(:send_string).and_return(0)
10
+
11
+ fake_context = double
12
+ expect(fake_context).to receive(:socket).and_return(fake_socket)
13
+ expect(::ZMQ::Context).to receive(:new).and_return(fake_context)
14
+ end
15
+
16
+ subject do
17
+ described_class.new(:host => '127.0.0.1', :port => 9400)
18
+ end
19
+
20
+ describe '#run' do
21
+ # not tested via unit tests
22
+ end
23
+
24
+ describe '#handle_request' do
25
+ # not tested via unit tests
26
+ end
27
+
28
+ describe '#initialize_buffers' do
29
+ # not tested via unit tests
30
+ end
31
+
32
+ describe '#send_data' do
33
+ # not tested via unit tests
34
+ end
35
+ end
@@ -0,0 +1,293 @@
1
+ require 'spec_helper'
2
+
3
+ require 'protobuf/rpc/service_directory'
4
+
5
+ RSpec.describe ::Protobuf::Rpc::ServiceDirectory do
6
+ subject { described_class.instance }
7
+
8
+ let(:echo_server) do
9
+ ::Protobuf::Rpc::DynamicDiscovery::Server.new(
10
+ :uuid => 'echo',
11
+ :address => '127.0.0.1',
12
+ :port => '1111',
13
+ :ttl => 10,
14
+ :services => %w(EchoService),
15
+ )
16
+ end
17
+
18
+ let(:hello_server) do
19
+ ::Protobuf::Rpc::DynamicDiscovery::Server.new(
20
+ :uuid => "hello",
21
+ :address => '127.0.0.1',
22
+ :port => "1112",
23
+ :ttl => 10,
24
+ :services => %w(HelloService),
25
+ )
26
+ end
27
+
28
+ let(:hello_server_with_short_ttl) do
29
+ ::Protobuf::Rpc::DynamicDiscovery::Server.new(
30
+ :uuid => "hello_server_with_short_ttl",
31
+ :address => '127.0.0.1',
32
+ :port => '1113',
33
+ :ttl => 1,
34
+ :services => %w(HelloService),
35
+ )
36
+ end
37
+
38
+ let(:combo_server) do
39
+ ::Protobuf::Rpc::DynamicDiscovery::Server.new(
40
+ :uuid => "combo",
41
+ :address => '127.0.0.1',
42
+ :port => '1114',
43
+ :ttl => 10,
44
+ :services => %w(HelloService EchoService),
45
+ )
46
+ end
47
+
48
+ before(:all) do
49
+ @address = "127.0.0.1"
50
+ @port = 33333
51
+ @socket = UDPSocket.new
52
+ EchoService = Class.new
53
+
54
+ described_class.address = @address
55
+ described_class.port = @port
56
+ end
57
+
58
+ def expect_event_trigger(event)
59
+ expect(::ActiveSupport::Notifications).to receive(:instrument)
60
+ .with(event, hash_including(:listing => an_instance_of(::Protobuf::Rpc::ServiceDirectory::Listing))).once
61
+ end
62
+
63
+ def send_beacon(type, server)
64
+ type = type.to_s.upcase
65
+ beacon = ::Protobuf::Rpc::DynamicDiscovery::Beacon.new(
66
+ :server => server,
67
+ :beacon_type => ::Protobuf::Rpc::DynamicDiscovery::BeaconType.fetch(type),
68
+ )
69
+
70
+ @socket.send(beacon.encode, 0, @address, @port)
71
+ sleep 0.01 # give the service directory time to process the beacon
72
+ end
73
+
74
+ it "should be a singleton" do
75
+ expect(subject).to be_a_kind_of(Singleton)
76
+ end
77
+
78
+ it "should be configured to listen to address 127.0.0.1" do
79
+ expect(described_class.address).to eq '127.0.0.1'
80
+ end
81
+
82
+ it "should be configured to listen to port 33333" do
83
+ expect(described_class.port).to eq 33333
84
+ end
85
+
86
+ it "should defer .start to the instance#start" do
87
+ expect(described_class.instance).to receive(:start)
88
+ described_class.start
89
+ end
90
+
91
+ it "should yeild itself to blocks passed to .start" do
92
+ allow(described_class.instance).to receive(:start)
93
+ expect { |b| described_class.start(&b) }.to yield_with_args(described_class)
94
+ end
95
+
96
+ it "should defer .stop to the instance#stop" do
97
+ expect(described_class.instance).to receive(:stop)
98
+ described_class.stop
99
+ end
100
+
101
+ context "stopped" do
102
+ before { subject.stop }
103
+
104
+ describe "#lookup" do
105
+ it "should return nil" do
106
+ send_beacon(:heartbeat, echo_server)
107
+ expect(subject.lookup("EchoService")).to be_nil
108
+ end
109
+ end
110
+
111
+ describe "#restart" do
112
+ it "should start the service" do
113
+ subject.restart
114
+ expect(subject).to be_running
115
+ end
116
+ end
117
+
118
+ describe "#running" do
119
+ it "should be false" do
120
+ expect(subject).to_not be_running
121
+ end
122
+ end
123
+
124
+ describe "#stop" do
125
+ it "has no effect" do
126
+ subject.stop
127
+ end
128
+ end
129
+ end
130
+
131
+ context "started" do
132
+ before { subject.start }
133
+ after { subject.stop }
134
+
135
+ specify { expect(subject).to be_running }
136
+
137
+ it "should trigger added events" do
138
+ expect_event_trigger("directory.listing.added")
139
+ send_beacon(:heartbeat, echo_server)
140
+ end
141
+
142
+ it "should trigger updated events" do
143
+ send_beacon(:heartbeat, echo_server)
144
+ expect_event_trigger("directory.listing.updated")
145
+ send_beacon(:heartbeat, echo_server)
146
+ end
147
+
148
+ it "should trigger removed events" do
149
+ send_beacon(:heartbeat, echo_server)
150
+ expect_event_trigger("directory.listing.removed")
151
+ send_beacon(:flatline, echo_server)
152
+ end
153
+
154
+ describe "#all_listings_for" do
155
+ context "when listings are present" do
156
+ it "returns all listings for a given service" do
157
+ send_beacon(:heartbeat, hello_server)
158
+ send_beacon(:heartbeat, combo_server)
159
+
160
+ expect(subject.all_listings_for("HelloService").size).to eq(2)
161
+ end
162
+ end
163
+
164
+ context "when no listings are present" do
165
+ it "returns and empty array" do
166
+ expect(subject.all_listings_for("HelloService").size).to eq(0)
167
+ end
168
+ end
169
+ end
170
+
171
+ describe "#each_listing" do
172
+ it "should yield to a block for each listing" do
173
+ send_beacon(:heartbeat, hello_server)
174
+ send_beacon(:heartbeat, echo_server)
175
+ send_beacon(:heartbeat, combo_server)
176
+
177
+ expect do |block|
178
+ subject.each_listing(&block)
179
+ end.to yield_control.exactly(3).times
180
+ end
181
+ end
182
+
183
+ describe "#lookup" do
184
+ it "should provide listings by service" do
185
+ send_beacon(:heartbeat, hello_server)
186
+ expect(subject.lookup("HelloService").to_hash).to eq hello_server.to_hash
187
+ end
188
+
189
+ it "should return random listings" do
190
+ send_beacon(:heartbeat, hello_server)
191
+ send_beacon(:heartbeat, combo_server)
192
+
193
+ uuids = 100.times.map { subject.lookup("HelloService").uuid }
194
+ expect(uuids.count("hello")).to be_within(25).of(50)
195
+ expect(uuids.count("combo")).to be_within(25).of(50)
196
+ end
197
+
198
+ it "should not return expired listings" do
199
+ send_beacon(:heartbeat, hello_server_with_short_ttl)
200
+ sleep 5
201
+ expect(subject.lookup("HelloService")).to be_nil
202
+ end
203
+
204
+ it "should not return flatlined servers" do
205
+ send_beacon(:heartbeat, echo_server)
206
+ send_beacon(:heartbeat, combo_server)
207
+ send_beacon(:flatline, echo_server)
208
+
209
+ uuids = 100.times.map { subject.lookup("EchoService").uuid }
210
+ expect(uuids.count("combo")).to eq 100
211
+ end
212
+
213
+ it "should return up-to-date listings" do
214
+ send_beacon(:heartbeat, echo_server)
215
+ echo_server.port = "7777"
216
+ send_beacon(:heartbeat, echo_server)
217
+
218
+ expect(subject.lookup("EchoService").port).to eq "7777"
219
+ end
220
+
221
+ context 'when given service identifier is a class name' do
222
+ it 'returns the listing corresponding to the class name' do
223
+ send_beacon(:heartbeat, echo_server)
224
+ expect(subject.lookup(EchoService).uuid).to eq echo_server.uuid
225
+ end
226
+ end
227
+ end
228
+
229
+ describe "#restart" do
230
+ it "should clear all listings" do
231
+ send_beacon(:heartbeat, echo_server)
232
+ send_beacon(:heartbeat, combo_server)
233
+ subject.restart
234
+ expect(subject.lookup("EchoService")).to be_nil
235
+ end
236
+ end
237
+
238
+ describe "#running" do
239
+ it "should be true" do
240
+ expect(subject).to be_running
241
+ end
242
+ end
243
+
244
+ describe "#stop" do
245
+ it "should clear all listings" do
246
+ send_beacon(:heartbeat, echo_server)
247
+ send_beacon(:heartbeat, combo_server)
248
+ subject.stop
249
+ expect(subject.lookup("EchoService")).to be_nil
250
+ end
251
+
252
+ it "should stop the server" do
253
+ subject.stop
254
+ expect(subject).to_not be_running
255
+ end
256
+ end
257
+ end
258
+
259
+ if ENV.key?("BENCH")
260
+ context "performance" do
261
+ let(:servers) do
262
+ 100.times.map do |x|
263
+ ::Protobuf::Rpc::DynamicDiscovery::Server.new(
264
+ :uuid => "performance_server#{x + 1}",
265
+ :address => '127.0.0.1',
266
+ :port => (5555 + x).to_s,
267
+ :ttl => rand(1..5),
268
+ :services => 10.times.map { |y| "PerformanceService#{y}" },
269
+ )
270
+ end
271
+ end
272
+
273
+ before do
274
+ require 'benchmark'
275
+ subject.start
276
+ servers.each { |server| send_beacon(:heartbeat, server) }
277
+ end
278
+
279
+ after do
280
+ subject.stop
281
+ end
282
+
283
+ it "should perform lookups in constant time" do
284
+ print "\n\n"
285
+ Benchmark.bm(17) do |x|
286
+ x.report(" 1_000 lookups:") { 1_000.times { subject.lookup("PerformanceService#{rand(0..9)}") } }
287
+ x.report(" 10_000 lookups:") { 10_000.times { subject.lookup("PerformanceService#{rand(0..9)}") } }
288
+ x.report("100_000 lookups:") { 100_000.times { subject.lookup("PerformanceService#{rand(0..9)}") } }
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end