hoodoo 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/bin/hoodoo +5 -0
  3. data/lib/hoodoo.rb +27 -0
  4. data/lib/hoodoo/active.rb +32 -0
  5. data/lib/hoodoo/active/active_model/uuid_validator.rb +45 -0
  6. data/lib/hoodoo/active/active_record/base.rb +81 -0
  7. data/lib/hoodoo/active/active_record/creator.rb +134 -0
  8. data/lib/hoodoo/active/active_record/dated.rb +343 -0
  9. data/lib/hoodoo/active/active_record/error_mapping.rb +351 -0
  10. data/lib/hoodoo/active/active_record/finder.rb +606 -0
  11. data/lib/hoodoo/active/active_record/search_helper.rb +189 -0
  12. data/lib/hoodoo/active/active_record/secure.rb +431 -0
  13. data/lib/hoodoo/active/active_record/support.rb +106 -0
  14. data/lib/hoodoo/active/active_record/translated.rb +87 -0
  15. data/lib/hoodoo/active/active_record/uuid.rb +80 -0
  16. data/lib/hoodoo/active/active_record/writer.rb +321 -0
  17. data/lib/hoodoo/client.rb +23 -0
  18. data/lib/hoodoo/client/augmented_array.rb +29 -0
  19. data/lib/hoodoo/client/augmented_base.rb +168 -0
  20. data/lib/hoodoo/client/augmented_hash.rb +23 -0
  21. data/lib/hoodoo/client/client.rb +354 -0
  22. data/lib/hoodoo/client/endpoint/endpoint.rb +427 -0
  23. data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +180 -0
  24. data/lib/hoodoo/client/endpoint/endpoints/auto_session.rb +194 -0
  25. data/lib/hoodoo/client/endpoint/endpoints/http.rb +203 -0
  26. data/lib/hoodoo/client/endpoint/endpoints/http_based.rb +367 -0
  27. data/lib/hoodoo/client/endpoint/endpoints/not_found.rb +59 -0
  28. data/lib/hoodoo/client/headers.rb +269 -0
  29. data/lib/hoodoo/communicators.rb +23 -0
  30. data/lib/hoodoo/communicators/fast.rb +44 -0
  31. data/lib/hoodoo/communicators/pool.rb +601 -0
  32. data/lib/hoodoo/communicators/slow.rb +84 -0
  33. data/lib/hoodoo/data.rb +51 -0
  34. data/lib/hoodoo/data/resources/caller.rb +39 -0
  35. data/lib/hoodoo/data/resources/errors.rb +28 -0
  36. data/lib/hoodoo/data/resources/log.rb +31 -0
  37. data/lib/hoodoo/data/resources/session.rb +26 -0
  38. data/lib/hoodoo/data/types/error_primitive.rb +27 -0
  39. data/lib/hoodoo/data/types/permissions.rb +40 -0
  40. data/lib/hoodoo/data/types/permissions_defaults.rb +32 -0
  41. data/lib/hoodoo/data/types/permissions_full.rb +28 -0
  42. data/lib/hoodoo/data/types/permissions_resources.rb +31 -0
  43. data/lib/hoodoo/discovery.rb +20 -0
  44. data/lib/hoodoo/errors.rb +19 -0
  45. data/lib/hoodoo/errors/error_descriptions.rb +229 -0
  46. data/lib/hoodoo/errors/errors.rb +322 -0
  47. data/lib/hoodoo/generator.rb +139 -0
  48. data/lib/hoodoo/logger.rb +23 -0
  49. data/lib/hoodoo/logger/fast_writer.rb +27 -0
  50. data/lib/hoodoo/logger/flattener_mixin.rb +36 -0
  51. data/lib/hoodoo/logger/logger.rb +387 -0
  52. data/lib/hoodoo/logger/slow_writer.rb +49 -0
  53. data/lib/hoodoo/logger/writer_mixin.rb +52 -0
  54. data/lib/hoodoo/logger/writers/file_writer.rb +45 -0
  55. data/lib/hoodoo/logger/writers/log_entries_dot_com_writer.rb +64 -0
  56. data/lib/hoodoo/logger/writers/stream_writer.rb +43 -0
  57. data/lib/hoodoo/middleware.rb +33 -0
  58. data/lib/hoodoo/presenters.rb +45 -0
  59. data/lib/hoodoo/presenters/base.rb +281 -0
  60. data/lib/hoodoo/presenters/base_dsl.rb +519 -0
  61. data/lib/hoodoo/presenters/common_resource_fields.rb +31 -0
  62. data/lib/hoodoo/presenters/embedding.rb +232 -0
  63. data/lib/hoodoo/presenters/types/array.rb +118 -0
  64. data/lib/hoodoo/presenters/types/boolean.rb +26 -0
  65. data/lib/hoodoo/presenters/types/date.rb +26 -0
  66. data/lib/hoodoo/presenters/types/date_time.rb +26 -0
  67. data/lib/hoodoo/presenters/types/decimal.rb +47 -0
  68. data/lib/hoodoo/presenters/types/enum.rb +55 -0
  69. data/lib/hoodoo/presenters/types/field.rb +158 -0
  70. data/lib/hoodoo/presenters/types/float.rb +26 -0
  71. data/lib/hoodoo/presenters/types/hash.rb +361 -0
  72. data/lib/hoodoo/presenters/types/integer.rb +26 -0
  73. data/lib/hoodoo/presenters/types/object.rb +117 -0
  74. data/lib/hoodoo/presenters/types/string.rb +53 -0
  75. data/lib/hoodoo/presenters/types/tags.rb +24 -0
  76. data/lib/hoodoo/presenters/types/text.rb +26 -0
  77. data/lib/hoodoo/presenters/types/uuid.rb +54 -0
  78. data/lib/hoodoo/services.rb +34 -0
  79. data/lib/hoodoo/services/discovery/discoverers/by_consul.rb +66 -0
  80. data/lib/hoodoo/services/discovery/discoverers/by_convention.rb +173 -0
  81. data/lib/hoodoo/services/discovery/discoverers/by_drb/by_drb.rb +195 -0
  82. data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server.rb +166 -0
  83. data/lib/hoodoo/services/discovery/discoverers/by_drb/drb_server_start.rb +37 -0
  84. data/lib/hoodoo/services/discovery/discovery.rb +186 -0
  85. data/lib/hoodoo/services/discovery/results/for_amqp.rb +58 -0
  86. data/lib/hoodoo/services/discovery/results/for_http.rb +85 -0
  87. data/lib/hoodoo/services/discovery/results/for_local.rb +85 -0
  88. data/lib/hoodoo/services/discovery/results/for_remote.rb +57 -0
  89. data/lib/hoodoo/services/middleware/amqp_log_message.rb +186 -0
  90. data/lib/hoodoo/services/middleware/amqp_log_writer.rb +119 -0
  91. data/lib/hoodoo/services/middleware/endpoints/inter_resource_local.rb +130 -0
  92. data/lib/hoodoo/services/middleware/endpoints/inter_resource_remote.rb +202 -0
  93. data/lib/hoodoo/services/middleware/exception_reporting/base_reporter.rb +105 -0
  94. data/lib/hoodoo/services/middleware/exception_reporting/exception_reporting.rb +115 -0
  95. data/lib/hoodoo/services/middleware/exception_reporting/reporters/airbrake_reporter.rb +64 -0
  96. data/lib/hoodoo/services/middleware/exception_reporting/reporters/raygun_reporter.rb +63 -0
  97. data/lib/hoodoo/services/middleware/interaction.rb +127 -0
  98. data/lib/hoodoo/services/middleware/middleware.rb +2705 -0
  99. data/lib/hoodoo/services/middleware/rack_monkey_patch.rb +73 -0
  100. data/lib/hoodoo/services/services/context.rb +153 -0
  101. data/lib/hoodoo/services/services/implementation.rb +132 -0
  102. data/lib/hoodoo/services/services/interface.rb +934 -0
  103. data/lib/hoodoo/services/services/permissions.rb +250 -0
  104. data/lib/hoodoo/services/services/request.rb +189 -0
  105. data/lib/hoodoo/services/services/response.rb +316 -0
  106. data/lib/hoodoo/services/services/service.rb +141 -0
  107. data/lib/hoodoo/services/services/session.rb +729 -0
  108. data/lib/hoodoo/utilities.rb +12 -0
  109. data/lib/hoodoo/utilities/string_inquirer.rb +54 -0
  110. data/lib/hoodoo/utilities/utilities.rb +380 -0
  111. data/lib/hoodoo/utilities/uuid.rb +44 -0
  112. data/lib/hoodoo/version.rb +17 -0
  113. data/spec/active/active_record/base_spec.rb +57 -0
  114. data/spec/active/active_record/creator_spec.rb +88 -0
  115. data/spec/active/active_record/dated_spec.rb +248 -0
  116. data/spec/active/active_record/error_mapping_spec.rb +360 -0
  117. data/spec/active/active_record/finder_spec.rb +744 -0
  118. data/spec/active/active_record/search_helper_spec.rb +384 -0
  119. data/spec/active/active_record/secure_spec.rb +435 -0
  120. data/spec/active/active_record/support_spec.rb +225 -0
  121. data/spec/active/active_record/translated_spec.rb +19 -0
  122. data/spec/active/active_record/uuid_spec.rb +72 -0
  123. data/spec/active/active_record/writer_spec.rb +272 -0
  124. data/spec/alchemy/alchemy-amq.rb +33 -0
  125. data/spec/client/augmented_array_spec.rb +15 -0
  126. data/spec/client/augmented_base_spec.rb +50 -0
  127. data/spec/client/augmented_hash_spec.rb +15 -0
  128. data/spec/client/client_spec.rb +955 -0
  129. data/spec/client/endpoint/endpoint_spec.rb +70 -0
  130. data/spec/client/endpoint/endpoints/amqp_spec.rb +16 -0
  131. data/spec/client/endpoint/endpoints/auto_session_spec.rb +9 -0
  132. data/spec/client/endpoint/endpoints/http_based_spec.rb +9 -0
  133. data/spec/client/endpoint/endpoints/http_spec.rb +103 -0
  134. data/spec/client/endpoint/endpoints/not_found_spec.rb +35 -0
  135. data/spec/client/headers_spec.rb +172 -0
  136. data/spec/communicators/fast_spec.rb +9 -0
  137. data/spec/communicators/pool_spec.rb +339 -0
  138. data/spec/communicators/slow_spec.rb +15 -0
  139. data/spec/data/resources/caller_spec.rb +156 -0
  140. data/spec/data/resources/errors_spec.rb +22 -0
  141. data/spec/data/resources/log_spec.rb +20 -0
  142. data/spec/data/resources/session_spec.rb +15 -0
  143. data/spec/data/types/error_primitive_spec.rb +15 -0
  144. data/spec/data/types/permissions_defaults_spec.rb +25 -0
  145. data/spec/data/types/permissions_full_spec.rb +44 -0
  146. data/spec/data/types/permissions_resources_spec.rb +34 -0
  147. data/spec/data/types/permissions_spec.rb +37 -0
  148. data/spec/errors/error_descriptions_spec.rb +98 -0
  149. data/spec/errors/errors_spec.rb +346 -0
  150. data/spec/integration/service_actions_spec.rb +112 -0
  151. data/spec/logger/fast_writer_spec.rb +18 -0
  152. data/spec/logger/logger_spec.rb +259 -0
  153. data/spec/logger/slow_writer_spec.rb +144 -0
  154. data/spec/logger/writers/file_writer_spec.rb +37 -0
  155. data/spec/logger/writers/log_entries_dot_com_writer_spec.rb +29 -0
  156. data/spec/logger/writers/stream_writer_spec.rb +38 -0
  157. data/spec/presenters/base_dsl_spec.rb +111 -0
  158. data/spec/presenters/base_spec.rb +871 -0
  159. data/spec/presenters/common_resource_fields_spec.rb +30 -0
  160. data/spec/presenters/embedding_spec.rb +87 -0
  161. data/spec/presenters/types/array_spec.rb +249 -0
  162. data/spec/presenters/types/boolean_spec.rb +51 -0
  163. data/spec/presenters/types/date_spec.rb +57 -0
  164. data/spec/presenters/types/date_time_spec.rb +59 -0
  165. data/spec/presenters/types/decimal_spec.rb +58 -0
  166. data/spec/presenters/types/enum_spec.rb +71 -0
  167. data/spec/presenters/types/field_spec.rb +77 -0
  168. data/spec/presenters/types/float_spec.rb +50 -0
  169. data/spec/presenters/types/hash_spec.rb +1069 -0
  170. data/spec/presenters/types/integer_spec.rb +50 -0
  171. data/spec/presenters/types/object_spec.rb +177 -0
  172. data/spec/presenters/types/string_spec.rb +65 -0
  173. data/spec/presenters/types/tags_spec.rb +56 -0
  174. data/spec/presenters/types/text_spec.rb +50 -0
  175. data/spec/presenters/types/uuid_spec.rb +46 -0
  176. data/spec/presenters/walk_spec.rb +198 -0
  177. data/spec/services/discovery/discoverers/by_consul_spec.rb +29 -0
  178. data/spec/services/discovery/discoverers/by_convention_spec.rb +67 -0
  179. data/spec/services/discovery/discoverers/by_drb/by_drb_spec.rb +80 -0
  180. data/spec/services/discovery/discoverers/by_drb/drb_server_spec.rb +205 -0
  181. data/spec/services/discovery/discovery_spec.rb +73 -0
  182. data/spec/services/discovery/results/for_amqp_spec.rb +17 -0
  183. data/spec/services/discovery/results/for_http_spec.rb +37 -0
  184. data/spec/services/discovery/results/for_local_spec.rb +21 -0
  185. data/spec/services/discovery/results/for_remote_spec.rb +15 -0
  186. data/spec/services/middleware/amqp_log_message_spec.rb +60 -0
  187. data/spec/services/middleware/amqp_log_writer_spec.rb +95 -0
  188. data/spec/services/middleware/endpoints/inter_resource_local_spec.rb +9 -0
  189. data/spec/services/middleware/endpoints/inter_resource_remote_spec.rb +9 -0
  190. data/spec/services/middleware/exception_reporting/base_reporter_spec.rb +16 -0
  191. data/spec/services/middleware/exception_reporting/exception_reporting_spec.rb +92 -0
  192. data/spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb +24 -0
  193. data/spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb +23 -0
  194. data/spec/services/middleware/middleware_cors_spec.rb +93 -0
  195. data/spec/services/middleware/middleware_create_update_spec.rb +489 -0
  196. data/spec/services/middleware/middleware_dated_at_spec.rb +186 -0
  197. data/spec/services/middleware/middleware_exotic_communication_spec.rb +560 -0
  198. data/spec/services/middleware/middleware_logging_spec.rb +356 -0
  199. data/spec/services/middleware/middleware_multi_local_spec.rb +1094 -0
  200. data/spec/services/middleware/middleware_multi_remote_spec.rb +1440 -0
  201. data/spec/services/middleware/middleware_permissions_spec.rb +1014 -0
  202. data/spec/services/middleware/middleware_public_spec.rb +238 -0
  203. data/spec/services/middleware/middleware_spec.rb +1569 -0
  204. data/spec/services/middleware/string_inquirer_spec.rb +30 -0
  205. data/spec/services/services/application_spec.rb +74 -0
  206. data/spec/services/services/context_spec.rb +48 -0
  207. data/spec/services/services/implementation_spec.rb +45 -0
  208. data/spec/services/services/interface_spec.rb +262 -0
  209. data/spec/services/services/permissions_spec.rb +249 -0
  210. data/spec/services/services/request_spec.rb +95 -0
  211. data/spec/services/services/response_spec.rb +250 -0
  212. data/spec/services/services/session_spec.rb +432 -0
  213. data/spec/spec_helper.rb +298 -0
  214. data/spec/utilities/utilities_spec.rb +537 -0
  215. data/spec/utilities/uuid_spec.rb +20 -0
  216. metadata +615 -0
@@ -0,0 +1,198 @@
1
+ require "spec_helper"
2
+
3
+
4
+ # This specific file just tests the presenter layer "#walk" method. It
5
+ # uses (at the time of writing) every single kind of schema field to
6
+ # varying degrees (where possible, e.g. "object") of complexity and
7
+ # then runs one "walk" call over the whole thing to verify that it does
8
+ # get called on every node.
9
+
10
+ describe Hoodoo::Presenters::Base do
11
+ before do
12
+ class TestWalkPresenterA < Hoodoo::Presenters::Base
13
+ schema do
14
+
15
+ # Simple fields
16
+
17
+ boolean :test_boolean
18
+ datetime :test_datetime
19
+ date :test_date
20
+ decimal :test_decimal, :precision => 2
21
+ enum :test_enum, :from => [ :one, :two ]
22
+ float :test_float
23
+ integer :test_integer
24
+ string :test_string, :length => 8
25
+ tags :test_tags
26
+ text :test_text
27
+ uuid :test_uuid
28
+
29
+ # Objects, in their various permitted forms
30
+
31
+ object :test_object_2 do
32
+ text :test_object_2_text_1
33
+ text :test_object_2_text_2
34
+ end
35
+
36
+ object :test_object_3 do
37
+ text :test_object_3_text_1
38
+ object :test_object_3_object_1 do
39
+ text :test_object_3_object_1_text_1
40
+ end
41
+ array :test_object_3_array_1 do
42
+ text :test_object_3_array_1_text_1
43
+ text :test_object_3_array_1_text_2
44
+ end
45
+ text :test_object_3_text_2
46
+ end
47
+
48
+ # Arrays, in their various permitted forms
49
+
50
+ array :text_array_1
51
+
52
+ array :test_array_2 do
53
+ text :test_array_2_text_1
54
+ text :test_array_2_text_2
55
+ end
56
+
57
+ array :test_array_3 do
58
+ text :test_array_3_text_1
59
+ object :test_array_3_object_1 do
60
+ text :test_array_3_object_1_text_1
61
+ text :test_array_3_object_1_text_2
62
+ end
63
+ text :test_array_3_text_2
64
+ end
65
+
66
+ # Hashes, in their various complex permitted forms
67
+
68
+ hash :test_hash_1
69
+
70
+ hash :test_hash_2 do
71
+ key :test_hash_2_key_1 do
72
+ text :test_hash_2_key_1_text_1
73
+ object :test_hash_2_key_1_object_1 do
74
+ text :test_hash_2_key_1_object_1_text_1
75
+ end
76
+ end
77
+ key :test_hash_2_key_2 do
78
+ array :test_hash_2_key_2_array_1 do
79
+ text :test_hash_2_key_2_array_1_text_1
80
+ end
81
+ end
82
+ end
83
+
84
+ hash :test_hash_3 do
85
+ keys do
86
+ text :test_hash_3_keys_text_1
87
+ object :test_hash_3_keys_object_1 do
88
+ text :test_hash_3_keys_object_1_text_1
89
+ end
90
+ array :test_hash_3_keys_array_1 do
91
+ text :test_hash_3_keys_array_1_text_1
92
+ end
93
+ end
94
+ end
95
+
96
+ hash :test_hash_4 do
97
+ keys :length => 4
98
+ end
99
+
100
+ end # 'schema do'
101
+ end # 'class TestWalkPresenter < Hoodoo::Presenters::Base'
102
+
103
+ class TestWalkPresenterB < Hoodoo::Presenters::Base
104
+ schema do
105
+ text :simple_text
106
+ end
107
+ end
108
+
109
+ class TestWalkPresenterC < Hoodoo::Presenters::Base
110
+ schema do
111
+ end
112
+ end
113
+
114
+ end # 'before do'
115
+
116
+ context '#walk' do
117
+ it 'handles complex tree' do
118
+ names = []
119
+
120
+ TestWalkPresenterA.walk do | property |
121
+ names << property.name
122
+ end
123
+
124
+ expected_names = [ '' ] + %w{
125
+ test_boolean
126
+ test_datetime
127
+ test_date
128
+ test_decimal
129
+ test_enum
130
+ test_float
131
+ test_integer
132
+ test_string
133
+ test_tags
134
+ test_text
135
+ test_uuid
136
+ test_object_2
137
+ test_object_2_text_1
138
+ test_object_2_text_2
139
+ test_object_3
140
+ test_object_3_text_1
141
+ test_object_3_object_1
142
+ test_object_3_object_1_text_1
143
+ test_object_3_array_1
144
+ test_object_3_array_1_text_1
145
+ test_object_3_array_1_text_2
146
+ test_object_3_text_2
147
+ text_array_1
148
+ test_array_2
149
+ test_array_2_text_1
150
+ test_array_2_text_2
151
+ test_array_3
152
+ test_array_3_text_1
153
+ test_array_3_object_1
154
+ test_array_3_object_1_text_1
155
+ test_array_3_object_1_text_2
156
+ test_array_3_text_2
157
+ test_hash_1
158
+ test_hash_2
159
+ test_hash_2_key_1
160
+ test_hash_2_key_1_text_1
161
+ test_hash_2_key_1_object_1
162
+ test_hash_2_key_1_object_1_text_1
163
+ test_hash_2_key_2
164
+ test_hash_2_key_2_array_1
165
+ test_hash_2_key_2_array_1_text_1
166
+ test_hash_3
167
+ test_hash_3_keys_text_1
168
+ test_hash_3_keys_object_1
169
+ test_hash_3_keys_object_1_text_1
170
+ test_hash_3_keys_array_1
171
+ test_hash_3_keys_array_1_text_1
172
+ test_hash_4
173
+ }
174
+
175
+ expect( names ).to eq( expected_names )
176
+ end
177
+
178
+ it 'handles simple tree' do
179
+ names = []
180
+
181
+ TestWalkPresenterB.walk do | property |
182
+ names << property.name
183
+ end
184
+
185
+ expect( names ).to eq( [ '', 'simple_text' ] )
186
+ end
187
+
188
+ it 'handles empty tree' do
189
+ names = []
190
+
191
+ TestWalkPresenterC.walk do | property |
192
+ names << property.name
193
+ end
194
+
195
+ expect( names ).to eq( [ '' ] )
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hoodoo::Services::Discovery::ByConsul do
4
+ before :each do
5
+ @d = described_class.new
6
+ end
7
+
8
+ # TODO: Assume static mapping and no Consul communication to mock out.
9
+
10
+ it 'announces' do
11
+ result = @d.announce( 'Version', '2' ) # Intentional string use
12
+ expect( result ).to be_a( Hoodoo::Services::Discovery::ForAMQP )
13
+ expect( result.resource ).to eq( :Version )
14
+ expect( result.version ).to eq( 2 )
15
+ expect( result.queue_name ).to eq( 'service.version' )
16
+ expect( result.equivalent_path ).to eq( '/v2/versions')
17
+ end
18
+
19
+ it 'discovers' do
20
+ result = @d.announce( 'Version', 2 )
21
+ @d.instance_variable_set( '@known_local_resources', {} ) # Hack for test!
22
+
23
+ result = @d.discover( :Version, 2 )
24
+ expect( result.resource ).to eq( :Version )
25
+ expect( result.version ).to eq( 2 )
26
+ expect( result.queue_name ).to eq( 'service.version' )
27
+ expect( result.equivalent_path ).to eq( '/v2/versions')
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hoodoo::Services::Discovery::ByConvention do
4
+ context 'with default routing' do
5
+ before :each do
6
+ @d = described_class.new( :base_uri => 'http://pond.org.uk' )
7
+ end
8
+
9
+ it 'announces' do
10
+ result = @d.announce( 'Apple', '3' ) # Intentional string use
11
+ expect( result ).to be_a( Hoodoo::Services::Discovery::ForHTTP )
12
+ expect( result.resource ).to eq( :Apple )
13
+ expect( result.version ).to eq( 3 )
14
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v3/apples')
15
+
16
+ result = @d.announce( 'Sheep', 2 )
17
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v2/sheep')
18
+ end
19
+
20
+ it 'discovers' do
21
+ @d.announce( 'Apple', 3 )
22
+ @d.instance_variable_set( '@known_local_resources', {} ) # Hack for test!
23
+
24
+ result = @d.discover( :Apple, 3 )
25
+ expect( result ).to be_a( Hoodoo::Services::Discovery::ForHTTP )
26
+ expect( result.resource ).to eq( :Apple )
27
+ expect( result.version ).to eq( 3 )
28
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v3/apples')
29
+ end
30
+ end
31
+
32
+ context 'with overridden routing' do
33
+ before :each do
34
+ @d = described_class.new(
35
+ :base_uri => 'http://pond.org.uk',
36
+ :routing => {
37
+ :Version => { 1 => '/v1/version', 2 => '/version_2/version_singleton' },
38
+ :Health => { 2 => '/v2/health' }
39
+ }
40
+ )
41
+ end
42
+
43
+ it 'discovers' do
44
+ @d.announce( :Version, 1 )
45
+ @d.announce( 'Version', 2 ) # Intentional string use
46
+ @d.announce( :Version, 3 )
47
+ @d.announce( :Apple, 3 )
48
+ @d.announce( :Health, 1 )
49
+ @d.announce( :Health, 2 )
50
+
51
+ @d.instance_variable_set( '@known_local_resources', {} ) # Hack for test!
52
+
53
+ result = @d.discover( :Version, 1 )
54
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v1/version')
55
+ result = @d.discover( :Version, 2 )
56
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/version_2/version_singleton')
57
+ result = @d.discover( :Version, 3 )
58
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v3/versions')
59
+ result = @d.discover( :Apple, 3 )
60
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v3/apples')
61
+ result = @d.discover( :Health, 1 )
62
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v1/healths')
63
+ result = @d.discover( :Health, 2 )
64
+ expect( result.endpoint_uri.to_s ).to eq( 'http://pond.org.uk/v2/health')
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ # A lot of this class is already covered by tests elsewhere, e.g. the
4
+ # drb_server_spec.rb stuff (via the middleware integration test part).
5
+
6
+ describe Hoodoo::Services::Discovery::ByDRb do
7
+
8
+ # Shut down a DRb service expected to be running (in a thread) on
9
+ # the given port.
10
+ #
11
+ def shut_down_drb_service_on( port )
12
+ begin
13
+ Timeout::timeout( 10 ) do
14
+ loop do
15
+ begin
16
+ client = DRbObject.new_with_uri( Hoodoo::Services::Discovery::ByDRb::DRbServer.uri( port ) )
17
+ client.ping()
18
+ client.stop()
19
+ break
20
+ rescue DRb::DRbConnError
21
+ sleep 0.1
22
+ end
23
+ end
24
+ end
25
+ rescue Timeout::Error
26
+ raise "Timed out while waiting for DRb service to communicate"
27
+ end
28
+ end
29
+
30
+ # This also tests in passing specifying a port number right through
31
+ # the discoverer to the CLI script that starts a DRb server up.
32
+ #
33
+ # If you get timeouts from the test, it's likely that the port number
34
+ # hasn't reached the server startup script and the server has come up
35
+ # on a different port.
36
+ #
37
+ it 'runs a DRb service which can be pinged and shuts down' do
38
+ expect {
39
+ port = Hoodoo::Utilities.spare_port().to_s
40
+
41
+ discoverer = Hoodoo::Services::Discovery::ByDRb.new( :drb_port => port )
42
+ discoverer.announce( :Foo, 1, :host => '127.0.0.1', :port => '9292' )
43
+
44
+ shut_down_drb_service_on( port )
45
+ }.to_not raise_error
46
+ end
47
+
48
+ # Similar to the above, but this tests passing in a full URI and assuming
49
+ # that the service is already running.
50
+ #
51
+ it 'can contact an existing DRb server' do
52
+ expect {
53
+ port = Hoodoo::Utilities.spare_port().to_s
54
+
55
+ discoverer = Hoodoo::Services::Discovery::ByDRb.new( :drb_port => port )
56
+ discoverer.announce( :Foo, 1, :host => '127.0.0.1', :port => '9292' )
57
+
58
+ discoverer = Hoodoo::Services::Discovery::ByDRb.new(
59
+ :drb_uri => Hoodoo::Services::Discovery::ByDRb::DRbServer.uri( port )
60
+ )
61
+
62
+ expect( discoverer.discover( :Foo, 1 ) ).to be_a( Hoodoo::Services::Discovery::ForHTTP )
63
+
64
+ shut_down_drb_service_on( port )
65
+ }.to_not raise_error
66
+ end
67
+
68
+ it 'complains if it cannot contact an existing DRb server' do
69
+ port = Hoodoo::Utilities.spare_port().to_s
70
+ uri = Hoodoo::Services::Discovery::ByDRb::DRbServer.uri( port )
71
+
72
+ expect {
73
+ discoverer = Hoodoo::Services::Discovery::ByDRb.new( :drb_uri => uri )
74
+ discoverer.discover( :Foo, 1 )
75
+ }.to raise_error(
76
+ RuntimeError,
77
+ "Hoodoo::Services::Discovery::ByDRb could not contact a DRb service registry at #{ uri }"
78
+ )
79
+ end
80
+ end
@@ -0,0 +1,205 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Hoodoo::Services::Discovery::ByDRb::DRbServer do
4
+
5
+ # When running tests we can't assume any particular static port is free
6
+ # on the test machine, so we must get a port dynamically. Since it might
7
+ # take a little while for a DRb server to fully shut down "behind the
8
+ # scenes" when we ask it to stop, its claimed port might not be free by
9
+ # the time the 'next test' runs, so we ask for a spare port for each
10
+ # test that runs.
11
+ #
12
+ before :each do
13
+ @drb_uri = "druby://127.0.0.1:#{ Hoodoo::Utilities.spare_port() }"
14
+ end
15
+
16
+ context "class instance" do
17
+ before do
18
+ @inst = described_class.new
19
+ end
20
+
21
+ it 'adds and reads endpoints' do
22
+ @inst.add( :Foo, 2, 'http://localhost:3030/v2/foo' )
23
+ @inst.add( :Foo, 1, 'http://127.0.0.1:3031/v1/foo' )
24
+ @inst.add( :Bar, 1, 'http://0.0.0.0:3032/v1/bar' )
25
+
26
+ expect( @inst.find( :Foo, 1 ) ).to eq( 'http://127.0.0.1:3031/v1/foo' )
27
+ expect( @inst.find( :Bar, 1 ) ).to eq( 'http://0.0.0.0:3032/v1/bar' )
28
+ expect( @inst.find( :Foo, 2 ) ).to eq( 'http://localhost:3030/v2/foo' )
29
+ expect( @inst.find( :Bar, 2 ) ).to be_nil
30
+ end
31
+
32
+ # RCov report coverage only; tests elsewhere call these but code runs
33
+ # in unusual execution contexts and doesn't get reported as covered.
34
+ #
35
+ it '#ping' do
36
+ expect( @inst.ping() ).to eq( true )
37
+ end
38
+ end
39
+
40
+ context "via DRb" do
41
+ it 'starts as a server' do
42
+ DRb.start_service( @drb_uri, Hoodoo::Services::Discovery::ByDRb::FRONT_OBJECT )
43
+ @drb_server = DRbObject.new_with_uri( @drb_uri )
44
+
45
+ expect do
46
+ @drb_server.add( :FooS, 2, 'http://localhost:3030/v2/foo_s' )
47
+ end.to_not raise_error
48
+
49
+ DRb.stop_service
50
+ end
51
+
52
+ it 'runs in a thread, can be pinged and shuts down' do
53
+ expect {
54
+ port = Hoodoo::Utilities.spare_port().to_s
55
+
56
+ thread = Thread.new do
57
+ ENV[ 'HOODOO_DISCOVERY_BY_DRB_PORT_OVERRIDE' ] = port
58
+ described_class.start()
59
+ ENV.delete( 'HOODOO_DISCOVERY_BY_DRB_PORT_OVERRIDE' )
60
+ end
61
+
62
+ client = nil
63
+
64
+ begin
65
+ Timeout::timeout( 5 ) do
66
+ loop do
67
+ begin
68
+ drb_service = DRbObject.new_with_uri( described_class.uri() )
69
+ drb_service.ping()
70
+ drb_service.stop()
71
+ break
72
+ rescue DRb::DRbConnError
73
+ sleep 0.1
74
+ end
75
+ end
76
+ end
77
+ rescue Timeout::Error
78
+ raise "Timed out while waiting for DRb service to communicat"
79
+ end
80
+
81
+ # For good measure...
82
+ #
83
+ ENV.delete( 'HOODOO_DISCOVERY_BY_DRB_PORT_OVERRIDE' )
84
+
85
+ }.to_not raise_error
86
+ end
87
+
88
+ it 'starts as a client' do
89
+ expect {
90
+ DRb.start_service( @drb_uri, Hoodoo::Services::Discovery::ByDRb::FRONT_OBJECT )
91
+ @drb_server = DRbObject.new_with_uri( @drb_uri )
92
+ @drb_server.add( :FooS2, 2, 'http://localhost:3030/v2/foo_s2' )
93
+
94
+ Thread.new do
95
+ @drb_client = DRbObject.new_with_uri( @drb_uri )
96
+ @drb_client.add( :FooC, 2, 'http://localhost:3030/v2/foo_c' )
97
+ end.join
98
+
99
+ DRb.stop_service
100
+
101
+ }.to_not raise_error
102
+ end
103
+
104
+ it 'synchronises data' do
105
+ DRb.start_service( @drb_uri, Hoodoo::Services::Discovery::ByDRb::FRONT_OBJECT )
106
+ @drb_server = DRbObject.new_with_uri( @drb_uri )
107
+
108
+ @drb_server.add( :Foo1, 2, 'http://localhost:3030/v2/foo_1' )
109
+ @drb_server.add( :Foo1, 1, 'http://127.0.0.1:3031/v1/foo_1' )
110
+
111
+ one = Thread.new do
112
+ @drb_client = DRbObject.new_with_uri( @drb_uri )
113
+ @drb_client.add( :Bar1, 1, 'http://0.0.0.0:3032/v1/bar_1' )
114
+
115
+ expect( @drb_client.find( :Foo1, 1 ) ).to eq( 'http://127.0.0.1:3031/v1/foo_1' )
116
+ expect( @drb_client.find( :Foo1, 2 ) ).to eq( 'http://localhost:3030/v2/foo_1' )
117
+ expect( @drb_client.find( :Foo1, 3 ) ).to be_nil
118
+
119
+ @drb_client.add( :Bar1, 1, 'http://0.0.0.0:3032/v1/bar_1' )
120
+ end.join
121
+
122
+ expect( @drb_server.find( :Bar1, 1 ) ).to eq( 'http://0.0.0.0:3032/v1/bar_1' )
123
+
124
+ DRb.stop_service
125
+ end
126
+
127
+ it 'flushes' do
128
+ DRb.start_service( @drb_uri, Hoodoo::Services::Discovery::ByDRb::FRONT_OBJECT )
129
+ @drb_server = DRbObject.new_with_uri( @drb_uri )
130
+
131
+ @drb_server.add( :Foo1, 2, 'http://localhost:3030/v2/foo_1' )
132
+ @drb_server.add( :Foo1, 1, 'http://127.0.0.1:3031/v1/foo_1' )
133
+
134
+ expect( @drb_server.find( :Foo1, 2 ) ).to_not be_nil
135
+ expect( @drb_server.find( :Foo1, 1 ) ).to_not be_nil
136
+
137
+ @drb_server.flush
138
+
139
+ expect( @drb_server.find( :Foo1, 2 ) ).to be_nil
140
+ expect( @drb_server.find( :Foo1, 1 ) ).to be_nil
141
+
142
+ DRb.stop_service
143
+ end
144
+ end
145
+
146
+ # A lot of this is copied from service_middleware_multi_spec.rb and
147
+ # it'd be cleaner if all these tests were in that one file, but it
148
+ # is nice to keep the tests specifically aimed at DRb here (even if
149
+ # a whole bunch of other stuff gets caught in the integration test).
150
+
151
+ @time_now = Time.now.to_s
152
+
153
+ class RSpecTestTimeImplementation < Hoodoo::Services::Implementation
154
+ def list( context )
155
+ context.response.set_resources( [ { 'time' => @time_now } ] )
156
+ end
157
+ end
158
+
159
+ class RSpecTestTimeInterface < Hoodoo::Services::Interface
160
+ interface( :RSpecDRbTestTime ) { endpoint :rspec_drb_test_time, RSpecTestTimeImplementation }
161
+ end
162
+
163
+ class RSpecTestTime < Hoodoo::Services::Service
164
+ comprised_of RSpecTestTimeInterface
165
+ end
166
+
167
+ class RSpecTestClockImplementation < Hoodoo::Services::Implementation
168
+ def list( context )
169
+ context.response.set_resources( context.resource( :RSpecDRbTestTime ).list() + [ { 'clock' => 'responded' } ] )
170
+ end
171
+ end
172
+
173
+ class RSpecTestClockInterface < Hoodoo::Services::Interface
174
+ interface( :RSpecDRbTestClock ) { endpoint :rspec_drb_test_clock, RSpecTestClockImplementation }
175
+ end
176
+
177
+ class RSpecTestClock < Hoodoo::Services::Service
178
+ comprised_of RSpecTestClockInterface
179
+ end
180
+
181
+ context 'via middleware' do
182
+
183
+ before :all do
184
+ @port1 = spec_helper_start_svc_app_in_thread_for( RSpecTestClock )
185
+ @port2 = spec_helper_start_svc_app_in_thread_for( RSpecTestTime )
186
+ end
187
+
188
+ # This is a significant integration test; two real Webrick instances
189
+ # each with its own service on a free HTTP port; one talks to the other
190
+ # over local machine HTTP via the DRb service for discovery.
191
+ #
192
+ it 'properly supports service discovery' do
193
+ response = spec_helper_http( path: '/v1/rspec_drb_test_clock', port: @port1 )
194
+ expect( response.code ).to eq( '200' )
195
+
196
+ parsed = JSON.parse( response.body )
197
+ expect( parsed ).to eq( {
198
+ '_data' => [
199
+ { 'time' => @time_now },
200
+ { 'clock' => 'responded' }
201
+ ]
202
+ } )
203
+ end
204
+ end
205
+ end