hoodoo 1.0.2

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 (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,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hoodoo::Logger::FastWriter do
4
+
5
+ # Nothing much to do here as code is covered by logger_spec.rb. The only
6
+ # thing we make sure of here is that the stream writer tested there is a
7
+ # subclass of the thing this test would otherwise cover.
8
+ #
9
+ it 'is used by the expected writer' do
10
+ expect( Hoodoo::Logger::StreamWriter < described_class ).to eq( true )
11
+ end
12
+
13
+ it 'complains about missing subclass implementation' do
14
+ expect {
15
+ Hoodoo::Logger::FastWriter.new().report( 1, 2, 3, 4 )
16
+ }.to raise_error( RuntimeError )
17
+ end
18
+ end
@@ -0,0 +1,259 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hoodoo::Logger do
4
+
5
+ # ===========================================================================
6
+
7
+ context 'basic behaviour' do
8
+ before :each do
9
+ @logger = described_class.new
10
+ end
11
+
12
+ it 'has a debug level by default' do
13
+ expect( @logger.level ).to eq( :debug )
14
+ end
15
+
16
+ it 'has no writers by default' do
17
+ expect( $stdout ).to_not receive( :puts )
18
+ expect( $stderr ).to_not receive( :puts )
19
+
20
+ @logger.error( 'No writers' )
21
+ end
22
+
23
+ it 'complains about bad additions' do
24
+ expect {
25
+ @logger.add( Object.new )
26
+ }.to raise_error( RuntimeError )
27
+ end
28
+ end
29
+
30
+ # ===========================================================================
31
+
32
+ context 'pool operation' do
33
+ before :each do
34
+ @logger = described_class.new
35
+ @stderr_1 = Hoodoo::Logger::StreamWriter.new( $stderr )
36
+ @stderr_2 = Hoodoo::Logger::StreamWriter.new( $stderr )
37
+ @stderr_3 = Hoodoo::Logger::StreamWriter.new( $stderr )
38
+
39
+ # Test single & multiple additions in passing.
40
+ #
41
+ @logger.add( @stderr_1 )
42
+ @logger.add( @stderr_2, @stderr_3 )
43
+ end
44
+
45
+ it 'calls added instances' do
46
+ expect( @stderr_1 ).to receive( :report ).once
47
+ expect( @stderr_2 ).to receive( :report ).once
48
+ expect( @stderr_3 ).to receive( :report ).once
49
+ expect( $stderr ).to_not receive( :puts )
50
+
51
+ @logger.error( 'Three instances of StreamWriter' )
52
+ end
53
+
54
+ it 'removes requested instances' do
55
+ @logger.remove( @stderr_2 )
56
+
57
+ expect( @stderr_1 ).to receive( :report ).once
58
+ expect( @stderr_2 ).to_not receive( :report )
59
+ expect( @stderr_3 ).to receive( :report ).once
60
+ expect( $stderr ).to_not receive( :puts )
61
+
62
+ @logger.error( 'Two instances of StreamWriter' )
63
+ end
64
+
65
+ it 'removes all instances' do
66
+ @logger.remove_all
67
+
68
+ expect( @stderr_1 ).to_not receive( :report )
69
+ expect( @stderr_2 ).to_not receive( :report )
70
+ expect( @stderr_3 ).to_not receive( :report )
71
+ expect( $stderr ).to_not receive( :puts )
72
+
73
+ @logger.error( 'No instances of StreamWriter' )
74
+ end
75
+
76
+ it 'retrieves instances in order' do
77
+ expect( @logger.instances ).to eq( [ @stderr_1, @stderr_2, @stderr_3 ] )
78
+ end
79
+ end
80
+
81
+ # ===========================================================================
82
+
83
+ context 'structured logging' do
84
+ before :each do
85
+ @logger = described_class.new
86
+ @writer = Hoodoo::Logger::StreamWriter.new( $stderr )
87
+ @logger.add( @writer )
88
+ end
89
+
90
+ it 'makes a structured log entry' do
91
+ expect(@writer).to receive(:report).with(:debug, :ComponentName, :code_value, {'_data'=>[1,2,3]})
92
+ @logger.report(
93
+ :debug,
94
+ :ComponentName,
95
+ :code_value,
96
+ {'_data'=>[1,2,3]}
97
+ )
98
+ end
99
+
100
+ it 'obeys debug log level' do
101
+ expect(@writer).to receive(:report).once
102
+
103
+ @logger.level = :debug
104
+ @logger.report(:debug, :comp, :code, {})
105
+
106
+ expect(@writer).to_not receive(:report)
107
+
108
+ @logger.level = :info
109
+ @logger.report(:debug, :comp, :code, {})
110
+ @logger.level = :warn
111
+ @logger.report(:debug, :comp, :code, {})
112
+ @logger.level = :error
113
+ @logger.report(:debug, :comp, :code, {})
114
+ end
115
+
116
+ it 'obeys info log level' do
117
+ expect(@writer).to receive(:report).exactly(2).times
118
+
119
+ @logger.level = :debug
120
+ @logger.report(:info, :comp, :code, {})
121
+ @logger.level = :info
122
+ @logger.report(:info, :comp, :code, {})
123
+
124
+ expect(@writer).to_not receive(:report)
125
+
126
+ @logger.level = :warn
127
+ @logger.report(:info, :comp, :code, {})
128
+ @logger.level = :error
129
+ @logger.report(:info, :comp, :code, {})
130
+ end
131
+
132
+ it 'obeys warn log level' do
133
+ expect(@writer).to receive(:report).exactly(3).times
134
+
135
+ @logger.level = :debug
136
+ @logger.report(:warn, :comp, :code, {})
137
+ @logger.level = :info
138
+ @logger.report(:warn, :comp, :code, {})
139
+ @logger.level = :warn
140
+ @logger.report(:warn, :comp, :code, {})
141
+
142
+ expect(@writer).to_not receive(:report)
143
+
144
+ @logger.level = :error
145
+ @logger.report(:warn, :comp, :code, {})
146
+ end
147
+
148
+ it 'obeys error log level' do
149
+ expect(@writer).to receive(:report).exactly(4).times
150
+
151
+ @logger.level = :debug
152
+ @logger.report(:error, :comp, :code, {})
153
+ @logger.level = :info
154
+ @logger.report(:error, :comp, :code, {})
155
+ @logger.level = :warn
156
+ @logger.report(:error, :comp, :code, {})
157
+ @logger.level = :error
158
+ @logger.report(:error, :comp, :code, {})
159
+ end
160
+ end
161
+
162
+ # ===========================================================================
163
+
164
+ context 'legacy logging' do
165
+ before :each do
166
+ @logger = described_class.new
167
+ @writer = Hoodoo::Logger::StreamWriter.new( $stderr )
168
+ @logger.add( @writer )
169
+ end
170
+
171
+ it 'makes debug log entry' do
172
+ expect(@writer).to receive(:report).with(:debug, :Middleware, :log, {'_data'=>[1,2,3]})
173
+ @logger.debug(1,2,3)
174
+ end
175
+
176
+ it 'makes info log entry' do
177
+ expect(@writer).to receive(:report).with(:info, :Middleware, :log, {'_data'=>[2,3,4]})
178
+ @logger.info(2,3,4)
179
+ end
180
+
181
+ it 'makes info log entry' do
182
+ expect(@writer).to receive(:report).with(:warn, :Middleware, :log, {'_data'=>[3,4,5]})
183
+ @logger.warn(3,4,5)
184
+ end
185
+
186
+ it 'makes error log entry' do
187
+ expect(@writer).to receive(:report).with(:error, :Middleware, :log, {'_data'=>[4,5,6]})
188
+ @logger.error(4,5,6)
189
+ end
190
+
191
+ it 'customises component' do
192
+ logger = described_class.new(:Custom)
193
+ logger.add(@writer)
194
+ expect(@writer).to receive(:report).with(:error, :Custom, :log, {'_data'=>[4,5,6]})
195
+ logger.error(4,5,6)
196
+ end
197
+
198
+ it 'obeys debug log level' do
199
+ expect(@writer).to receive(:report).once
200
+
201
+ @logger.level = :debug
202
+ @logger.debug( 'data' )
203
+
204
+ expect(@writer).to_not receive(:report)
205
+
206
+ @logger.level = :info
207
+ @logger.debug( 'data' )
208
+ @logger.level = :warn
209
+ @logger.debug( 'data' )
210
+ @logger.level = :error
211
+ @logger.debug( 'data' )
212
+ end
213
+
214
+ it 'obeys info log level' do
215
+ expect(@writer).to receive(:report).exactly(2).times
216
+
217
+ @logger.level = :debug
218
+ @logger.info( 'data' )
219
+ @logger.level = :info
220
+ @logger.info( 'data' )
221
+
222
+ expect(@writer).to_not receive(:report)
223
+
224
+ @logger.level = :warn
225
+ @logger.info( 'data' )
226
+ @logger.level = :error
227
+ @logger.info( 'data' )
228
+ end
229
+
230
+ it 'obeys warn log level' do
231
+ expect(@writer).to receive(:report).exactly(3).times
232
+
233
+ @logger.level = :debug
234
+ @logger.warn( 'data' )
235
+ @logger.level = :info
236
+ @logger.warn( 'data' )
237
+ @logger.level = :warn
238
+ @logger.warn( 'data' )
239
+
240
+ expect(@writer).to_not receive(:report)
241
+
242
+ @logger.level = :error
243
+ @logger.warn( 'data' )
244
+ end
245
+
246
+ it 'obeys error log level' do
247
+ expect(@writer).to receive(:report).exactly(4).times
248
+
249
+ @logger.level = :debug
250
+ @logger.error( 'data' )
251
+ @logger.level = :info
252
+ @logger.error( 'data' )
253
+ @logger.level = :warn
254
+ @logger.error( 'data' )
255
+ @logger.level = :error
256
+ @logger.error( 'data' )
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hoodoo::Logger::SlowWriter do
4
+
5
+ # See fast_writer_spec.rb comments.
6
+ #
7
+ it 'is used by the expected writer' do
8
+ expect( Hoodoo::Logger::FileWriter < described_class ).to eq( true )
9
+ end
10
+
11
+ class RSpecTestSlowWriter < Hoodoo::Logger::SlowWriter
12
+ def report( a, b, c, d )
13
+ expectable_hook( a, b, c, d )
14
+ end
15
+ end
16
+
17
+ context 'with exceptions' do
18
+ class RSpecTestErrantSlowWriter < Hoodoo::Logger::SlowWriter
19
+ def report( a, b, c, d )
20
+ raise 'I am broken'
21
+ end
22
+ end
23
+
24
+ before :each do
25
+ @logger = Hoodoo::Logger.new
26
+ @logger.add( RSpecTestErrantSlowWriter.new )
27
+ end
28
+
29
+ it 'logs them' do
30
+ @logger.debug( 'Doh' )
31
+ end
32
+ end
33
+
34
+ context 'message dropping' do
35
+ before :each do
36
+
37
+ # This sync queue is pushed from the running test and popped from the
38
+ # communicators inside their message handler, so that we can force the
39
+ # communicators to halt "mid-message" by not pushing until we're ready.
40
+
41
+ $sync_queue = Queue.new
42
+ end
43
+
44
+ before :each do
45
+ @logger = Hoodoo::Logger.new
46
+ end
47
+
48
+ class RSpecTestDroppingSlowWriter < Hoodoo::Logger::SlowWriter
49
+ def initialize
50
+ @count = 0
51
+ end
52
+
53
+ attr_reader :count
54
+
55
+ # This consumes one message then tries to pop a queue item, forcing it
56
+ # to wait for the test code to push. This lets us control completely
57
+ # consistently thread execution, guaranteeing no further processing of
58
+ # log messages until we want to let it run.
59
+ #
60
+ def report( a, b, c, d )
61
+ $sync_queue.pop if @count == 0
62
+ @count += 1
63
+ end
64
+ end
65
+
66
+ # Cribbed from the communicators/pool_spec.rb approach, with the same
67
+ # limitations.
68
+ #
69
+ it 'reports dropped messages' do
70
+
71
+ args = [ :error, :CustomComponent, :custom_code, { :data => :foo } ]
72
+ writer = RSpecTestDroppingSlowWriter.new
73
+
74
+ @logger.add( writer )
75
+
76
+ # See communicators/pool_spec.rb for rationale.
77
+
78
+ expect(writer).to receive(:report).exactly(1).times.with( *args ).and_call_original
79
+ @logger.report( *args )
80
+
81
+ loop do
82
+ sleep 0.01
83
+ break if $sync_queue.num_waiting > 0
84
+ end
85
+
86
+ # See communicators/pool_spec.rb for rationale. Note the assumption
87
+ # here that the logger is running on a communicator pool, so the queue
88
+ # size there is applicable here. This makes the test potentially fragile.
89
+
90
+ limit = Hoodoo::Communicators::Pool::MAX_SLOW_QUEUE_SIZE
91
+ additional = 10
92
+
93
+ # See communicators/pool_spec.rb for rationale.
94
+
95
+ 1.upto( limit + additional ) do | i |
96
+ @logger.report( *args )
97
+ sleep 2 if i == 1
98
+ end
99
+
100
+ # See communicators/pool_spec.rb for rationale.
101
+
102
+ expect(writer).to receive(:report).exactly( limit ).times.with( *args ).and_call_original
103
+ $sync_queue << :go!
104
+
105
+ # See communicators/pool_spec.rb for rationale.
106
+
107
+ @logger.wait()
108
+
109
+ # See communicators/pool_spec.rb for rationale; send another report in,
110
+ # provoking first a 'dropped messages' log report.
111
+ #
112
+ # I cannot no matter how hard I try come up with a syntax for RSpec
113
+ # that expects the 'dropped messages' report then '*args'; it just
114
+ # messes up the test conditions ever time, causing timeouts in the
115
+ # processing thread, "writer.count" expectation failures (see end of
116
+ # test) and so-on.
117
+
118
+ expect(writer).to receive(:report).once.with(
119
+ :warn,
120
+ 'Hoodoo::Logger::SlowCommunicator',
121
+ 'dropped.messages',
122
+ "Logging flooded - #{ additional } messages dropped"
123
+ ).and_call_original
124
+
125
+ expect(writer).to receive(:report).once.with( *args ).and_call_original
126
+
127
+ @logger.report( *args )
128
+ @logger.wait()
129
+
130
+ # The writer counts only logged messages - the first 'sync up' message,
131
+ # 'limit' in the queue, 1 reporting the number of dropped messages and
132
+ # 1 that was sent to prompt that dropped messages report.
133
+ #
134
+ # Are you not seeing an expected count? It's possible that the RSpec
135
+ # message receiving expectations earlier were not met. If those fail,
136
+ # the test doesn't halt (theory - RSpec raises exceptions to detect
137
+ # this condition and the pool thread's aggressive exception handler hides
138
+ # all of that?) but the "and-call-original"'s never happen, so the counts
139
+ # are lower than they should be here.
140
+
141
+ expect( writer.count ).to eq( 1 + limit + 1 + 1 )
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Hoodoo::Logger::FileWriter do
5
+
6
+ before :all do
7
+ temp_name = Dir::Tmpname.make_tmpname( 'hoodoo_rspec_', nil )
8
+ @temp_path = File.join( Dir::Tmpname.tmpdir, temp_name )
9
+ end
10
+
11
+ after :all do
12
+ begin
13
+ File.unlink( @temp_path )
14
+ rescue
15
+ end
16
+ end
17
+
18
+ it 'writes to files' do
19
+
20
+ # Create the instance; should not write anything.
21
+ #
22
+ instance = described_class.new( @temp_path )
23
+ expect( File.exist?( @temp_path ) ).to be( false )
24
+
25
+ # Log a message.
26
+ #
27
+ time = Time.parse("2014-01-01 00:00:00 UTC")
28
+ expect( Time ).to receive( :now ).at_least( 1 ).times.and_return( time )
29
+
30
+ instance.report( :a, :b, :c, :d )
31
+ expect( File.exist?( @temp_path ) ).to be( true )
32
+
33
+ logged = File.read( @temp_path )
34
+ expect( logged ).to eq( "A [2014-01-01T00:00:00.000000Z] b - c: :d\n")
35
+
36
+ end
37
+ end