hoodoo 2.2.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b44ab5eb415262a966b85b5745d7babae95bcea72ad1f82dc17d9ba1b0e8aee6
4
- data.tar.gz: 7894b8277a7061f9ec1e83ab15fb6f25d92797cf3ad59e2a2d03968ac098b636
3
+ metadata.gz: 0e8b58918454743aba0a3c4b64ed5b16dded3369ce27868c4344386c83286c84
4
+ data.tar.gz: 37d7dc316771890f1ff8021420d34a6c12caeb9f7e6928f0d424700734d353c6
5
5
  SHA512:
6
- metadata.gz: c691cdaf17d8964a04edc102358485047a6b361147f5a14cc8d555772b4709f9dc903ae2d319c5392506330c0686c5cd09ed026bfc0470f923d39bc3d74a1e04
7
- data.tar.gz: d2325636825a764be468a6411efec5a9e6bfec2e6d6f5d06f2b404d16a0411b95a23e9499e578600649baadfe65f3069cbdce146367c1acfbbceadef255c2195
6
+ metadata.gz: 8908060c76f8dd1de5c031d4143a1c3f1e3481c1124d081a0b33c700330aa6a9bd903e811185f7a1beb8f14d5fe29b816acddd684d669eb3ecbf8a27848a6822
7
+ data.tar.gz: c5d7c0f1b3a00e1be635f5c10fc3c9b4a075bb76da1506cc4587d0d8a329a161c3ff935a370be941707eb75a5649fa1a1e666fa24bca07e23333f352df0f4552
@@ -65,7 +65,7 @@ module Hoodoo
65
65
  #
66
66
  DATETIME_IN_PAST_ONLY_PROPERTY_PROC = -> ( value ) {
67
67
  value = Hoodoo::Utilities.valid_iso8601_subset_datetime?( value )
68
- value = nil if value && value > DateTime.now
68
+ value = nil if value && Hoodoo::Utilities.is_in_future?( value )
69
69
  value || nil # => 'value' if 'value' is truthy, 'nil' if 'value' falsy
70
70
  }
71
71
 
@@ -260,14 +260,36 @@ module Hoodoo; module Services
260
260
  # host available.
261
261
  #
262
262
  def self.memcached_host
263
- ENV[ 'MEMCACHED_HOST' ] || ENV[ 'MEMCACHE_URL' ]
263
+
264
+ # See also ::clear_memcached_configuration_cache!.
265
+ #
266
+ @@memcached_host ||= ENV[ 'MEMCACHED_HOST' ] || ENV[ 'MEMCACHE_URL' ]
267
+
268
+ end
269
+
270
+ # This method is intended really just for testing purposes; it clears the
271
+ # internal cache of Memcached data read from environment variables.
272
+ #
273
+ def self.clear_memcached_configuration_cache!
274
+ @@memcached_host = nil
264
275
  end
265
276
 
266
277
  # Are we running on the queue, else (implied) a local HTTP server?
267
278
  #
268
279
  def self.on_queue?
269
- q = ENV[ 'AMQ_URI' ]
270
- q.nil? == false && q.empty? == false
280
+
281
+ # See also ::clear_queue_configuration_cache!.
282
+ #
283
+ @@amq_uri ||= ENV[ 'AMQ_URI' ]
284
+ @@amq_uri.nil? == false && @@amq_uri.empty? == false
285
+
286
+ end
287
+
288
+ # This method is intended really just for testing purposes; it clears the
289
+ # internal cache of AMQP queue data read from environment variables.
290
+ #
291
+ def self.clear_queue_configuration_cache!
292
+ @@amq_uri = nil
271
293
  end
272
294
 
273
295
  # Return a service 'name' derived from the service's collection of
@@ -340,6 +340,51 @@ module Hoodoo
340
340
  return value.is_a?( ::Date ) && value
341
341
  end
342
342
 
343
+ # Is the given Time, DateTime or String instance specifying a date-time
344
+ # that is in the future relevant to this executing environment's concept
345
+ # of "now", allowing for +CLOCK_DRIFT_TOLERANCE+? Returns +true+ if so,
346
+ # else +false+.
347
+ #
348
+ # Future date (clock drift) tolerance is specified in seconds using the
349
+ # +HOODOO_CLOCK_DRIFT_TOLERANCE+ environment variable. The default is 30
350
+ # seconds, as described in the relevant Hoodoo Guide:
351
+ #
352
+ # http://loyaltynz.github.io/hoodoo/guides_1000_env_vars.html#hoodoo_clock_drift_tolerance
353
+ #
354
+ # +input+:: A value that's passed to ::rationalise_datetime with the
355
+ # result checked against `now` allowing for clock drift.
356
+ #
357
+ # If the given input is not parseable as a date-time like object, then
358
+ # the method it will throw a RuntimeError exception via
359
+ # ::rationalise_datetime.
360
+ #
361
+ def self.is_in_future?( input )
362
+
363
+ # See also ::clear_clock_drift_configuration_cache!.
364
+ #
365
+ @@clock_drift_tolerance ||= (
366
+ ENV[ 'HOODOO_CLOCK_DRIFT_TOLERANCE' ].nil? ?
367
+ 30 :
368
+ ENV[ 'HOODOO_CLOCK_DRIFT_TOLERANCE' ].to_i
369
+ )
370
+
371
+ value = self.rationalise_datetime( input )
372
+
373
+ # Unlike Time, integer addition to DateTime adds days. There are 86400
374
+ # seconds per day, so below we add @@clock_drift_tolerance seconds.
375
+ #
376
+ value > DateTime.now + Rational(@@clock_drift_tolerance, 86400)
377
+
378
+ end
379
+
380
+ # This method is intended really just for testing purposes; it clears the
381
+ # internal cache of clock drift tolerance read from environment variable
382
+ # +HOODOO_CLOCK_DRIFT_TOLERANCE+.
383
+ #
384
+ def self.clear_clock_drift_configuration_cache!
385
+ @@clock_drift_tolerance = nil
386
+ end
387
+
343
388
  # Returns an ISO 8601 String equivalent of the given Time, Date or
344
389
  # DateTime instance as a full date-time with UTC timezone, with
345
390
  # "standard high precision" (for rendeirng consistency), subject to
@@ -12,11 +12,11 @@ module Hoodoo
12
12
  # The Hoodoo gem version. If this changes, be sure to re-run
13
13
  # <tt>bundle install</tt> or <tt>bundle update</tt>.
14
14
  #
15
- VERSION = '2.2.3'
15
+ VERSION = '2.3.0'
16
16
 
17
17
  # The Hoodoo gem date. If this changes, be sure to re-run
18
18
  # <tt>bundle install</tt> or <tt>bundle update</tt>.
19
19
  #
20
- DATE = '2018-02-19'
20
+ DATE = '2018-02-22'
21
21
 
22
22
  end
@@ -76,6 +76,21 @@ describe Hoodoo::Client::Headers do
76
76
  expect( described_class::DATETIME_IN_PAST_ONLY_PROPERTY_PROC.call( date_time_str ) ).to be_nil
77
77
  end
78
78
  end
79
+
80
+ # We assume good coverage for the Utility method below. If this header
81
+ # Proc is calling that and appears to be responding to its return value,
82
+ # that's good enough for us here.
83
+ #
84
+ it 'uses Hoodoo::Utilities::is_in_future? for is-future checks' do
85
+ date_time = DateTime.now - 10.seconds
86
+ date_time_str = Hoodoo::Utilities.nanosecond_iso8601( date_time )
87
+
88
+ expect( Hoodoo::Utilities ).to receive( :is_in_future? ).with( date_time ).once.and_return( false )
89
+ expect( described_class::DATETIME_IN_PAST_ONLY_PROPERTY_PROC.call( date_time_str ) ).to eq( date_time )
90
+
91
+ expect( Hoodoo::Utilities ).to receive( :is_in_future? ).with( date_time ).once.and_return( true )
92
+ expect( described_class::DATETIME_IN_PAST_ONLY_PROPERTY_PROC.call( date_time_str ) ).to be_nil
93
+ end
79
94
  end
80
95
 
81
96
  it 'DATETIME_WRITER_PROC calls rationalisation method' do
@@ -99,7 +99,9 @@ describe Hoodoo::Services::Middleware do
99
99
  context 'off queue' do
100
100
  before :each do
101
101
  @old_queue = ENV[ 'AMQ_URI' ]
102
+
102
103
  ENV[ 'AMQ_URI' ] = nil
104
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
103
105
 
104
106
  @cvar = false
105
107
  if Hoodoo::Services::Middleware.class_variable_defined?( '@@alchemy' )
@@ -110,6 +112,7 @@ describe Hoodoo::Services::Middleware do
110
112
 
111
113
  after :each do
112
114
  ENV[ 'AMQ_URI' ] = @old_queue
115
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
113
116
 
114
117
  if Hoodoo::Services::Middleware.class_variable_defined?( '@@alchemy' )
115
118
  if @cvar == true
@@ -146,7 +149,9 @@ describe Hoodoo::Services::Middleware do
146
149
  context 'on queue' do
147
150
  before :each do
148
151
  @old_queue = ENV[ 'AMQ_URI' ]
152
+
149
153
  ENV[ 'AMQ_URI' ] = 'amqp://test:test@127.0.0.1'
154
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
150
155
 
151
156
  @cvar = false
152
157
  if Hoodoo::Services::Middleware.class_variable_defined?( '@@alchemy' )
@@ -157,6 +162,7 @@ describe Hoodoo::Services::Middleware do
157
162
 
158
163
  after :each do
159
164
  ENV[ 'AMQ_URI' ] = @old_queue
165
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
160
166
 
161
167
  if Hoodoo::Services::Middleware.class_variable_defined?( '@@alchemy' )
162
168
  if @cvar == true
@@ -178,31 +178,86 @@ describe Hoodoo::Services::Middleware do
178
178
  end
179
179
 
180
180
  context 'utility methods' do
181
+ before :each do
182
+ Hoodoo::Services::Middleware.clear_memcached_configuration_cache!
183
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
184
+ end
185
+
186
+ after :each do
187
+ Hoodoo::Services::Middleware.clear_memcached_configuration_cache!
188
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
189
+ end
190
+
181
191
  it 'should know about Memcached via environment variable' do
182
- old = ENV[ 'MEMCACHED_HOST' ]
183
- ENV[ 'MEMCACHED_HOST' ] = nil
184
- expect(Hoodoo::Services::Middleware.has_memcached?).to eq(false)
185
- ENV[ 'MEMCACHED_HOST' ] = 'foo'
186
- expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
187
- ENV[ 'MEMCACHED_HOST' ] = old
192
+ spec_helper_change_environment( 'MEMCACHED_HOST', nil ) do
193
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(false)
194
+ end
195
+
196
+ spec_helper_change_environment( 'MEMCACHED_HOST', 'foo' ) do
197
+ Hoodoo::Services::Middleware.clear_memcached_configuration_cache!
198
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
199
+ end
200
+ end
201
+
202
+ it 'caches Memcached environment variable value' do
203
+ spec_helper_change_environment( 'MEMCACHED_HOST', 'foo' ) do
204
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
205
+
206
+ # Cached value -> result of check remains 'true', since prior
207
+ # result is cached.
208
+ #
209
+ spec_helper_change_environment( 'MEMCACHED_HOST', nil ) do
210
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
211
+ end
212
+ end
188
213
  end
189
214
 
190
215
  it 'should know about Memcached via legacy environment variable' do
191
- old = ENV[ 'MEMCACHED_HOST' ]
192
- ENV[ 'MEMCACHED_HOST' ] = nil
193
- expect(Hoodoo::Services::Middleware.has_memcached?).to eq(false)
194
- ENV[ 'MEMCACHED_HOST' ] = 'foo'
195
- expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
196
- ENV[ 'MEMCACHED_HOST' ] = old
216
+ spec_helper_change_environment( 'MEMCACHE_URL', nil ) do
217
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(false)
218
+ end
219
+
220
+ spec_helper_change_environment( 'MEMCACHE_URL', 'foo' ) do
221
+ Hoodoo::Services::Middleware.clear_memcached_configuration_cache!
222
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
223
+ end
224
+ end
225
+
226
+ it 'caches legacy Memcached environment variable value' do
227
+ spec_helper_change_environment( 'MEMCACHE_URL', 'foo' ) do
228
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
229
+
230
+ # Cached value -> result of check remains 'true', since prior
231
+ # result is cached.
232
+ #
233
+ spec_helper_change_environment( 'MEMCACHE_URL', nil ) do
234
+ expect(Hoodoo::Services::Middleware.has_memcached?).to eq(true)
235
+ end
236
+ end
197
237
  end
198
238
 
199
239
  it 'should know about a queue' do
200
- old = ENV[ 'AMQ_URI' ]
201
- ENV[ 'AMQ_URI' ] = nil
202
- expect(Hoodoo::Services::Middleware.on_queue?).to eq(false)
203
- ENV[ 'AMQ_URI' ] = 'foo'
204
- expect(Hoodoo::Services::Middleware.on_queue?).to eq(true)
205
- ENV[ 'AMQ_URI' ] = old
240
+ spec_helper_change_environment( 'AMQ_URI', nil ) do
241
+ expect(Hoodoo::Services::Middleware.on_queue?).to eq(false)
242
+ end
243
+
244
+ spec_helper_change_environment( 'AMQ_URI', 'foo' ) do
245
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
246
+ expect(Hoodoo::Services::Middleware.on_queue?).to eq(true)
247
+ end
248
+ end
249
+
250
+ it 'caches queue environment variable value' do
251
+ spec_helper_change_environment( 'AMQ_URI', 'foo' ) do
252
+ expect(Hoodoo::Services::Middleware.on_queue?).to eq(true)
253
+
254
+ # Cached value -> result of check remains 'true', since prior
255
+ # result is cached.
256
+ #
257
+ spec_helper_change_environment( 'AMQ_URI', nil ) do
258
+ expect(Hoodoo::Services::Middleware.on_queue?).to eq(true)
259
+ end
260
+ end
206
261
  end
207
262
  end
208
263
 
@@ -21,7 +21,10 @@ shared_examples 'an AMQP-based middleware/client endpoint' do |optional_extra_he
21
21
  before :each do
22
22
  @optional_extra_header_hash = optional_extra_header_hash || {}
23
23
  @old_queue = ENV[ 'AMQ_URI' ]
24
+
24
25
  ENV[ 'AMQ_URI' ] = 'amqp://test:test@127.0.0.1'
26
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
27
+
25
28
  @mw = Hoodoo::Services::Middleware.new( RSpecTestServiceExoticStub.new )
26
29
 
27
30
  @cvar = false
@@ -39,6 +42,7 @@ shared_examples 'an AMQP-based middleware/client endpoint' do |optional_extra_he
39
42
 
40
43
  after :each do
41
44
  ENV[ 'AMQ_URI' ] = @old_queue
45
+ Hoodoo::Services::Middleware.clear_queue_configuration_cache!
42
46
 
43
47
  if Hoodoo::Services::Middleware.class_variable_defined?( '@@alchemy' )
44
48
  if @cvar == true
data/spec/spec_helper.rb CHANGED
@@ -380,6 +380,19 @@ def spec_helper_count_database_calls_in( &block )
380
380
  return count
381
381
  end
382
382
 
383
+ # Change a named environment varible's value and call a given block.
384
+ # Afterwards, restore the old value of that variable.
385
+
386
+ def spec_helper_change_environment( name, value, &block )
387
+ old_value = ENV[ name ]
388
+ begin
389
+ ENV[ name ] = value
390
+ yield
391
+ ensure
392
+ ENV[ name ] = old_value
393
+ end
394
+ end
395
+
383
396
  # In Ruby 2.5.0 the Ruby team removed <tt>Dir::Tmpname.make_tmpname</tt>:
384
397
  #
385
398
  # https://github.com/ruby/ruby/commit/25d56ea7b7b52dc81af30c92a9a0e2d2dab6ff27
@@ -485,6 +485,66 @@ describe Hoodoo::Utilities do
485
485
  end
486
486
  end
487
487
 
488
+ describe '#is_in_future?' do
489
+ before :each do
490
+ @old_drift = ENV[ 'HOODOO_CLOCK_DRIFT_TOLERANCE' ]
491
+ ENV.delete( 'HOODOO_CLOCK_DRIFT_TOLERANCE' )
492
+ Hoodoo::Utilities.clear_clock_drift_configuration_cache!
493
+
494
+ @default = 30
495
+ end
496
+
497
+ after :all do
498
+ ENV[ 'HOODOO_CLOCK_DRIFT_TOLERANCE' ] = @old_drift
499
+ end
500
+
501
+ it 'says "no" for "now"' do
502
+ expect( Hoodoo::Utilities.is_in_future?( Time.now ) ).to eq( false )
503
+ end
504
+
505
+ it 'says "no" inside default drift allowance' do
506
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + ( @default / 2 ) ) ).to eq( false )
507
+ end
508
+
509
+ # Hoodoo Guides: "...less than or equal to... ...is permitted...".
510
+ #
511
+ it 'says "no" at default drift allowance' do
512
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + @default ) ).to eq( false )
513
+ end
514
+
515
+ it 'says "yes" outside default drift allowance' do
516
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + @default + 1 ) ).to eq( true )
517
+ end
518
+
519
+ it 'drift allowance can be reconfigured' do
520
+ spec_helper_change_environment( 'HOODOO_CLOCK_DRIFT_TOLERANCE', '10' ) do
521
+ Hoodoo::Utilities.clear_clock_drift_configuration_cache!
522
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + 10 ) ).to eq( false )
523
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + 11 ) ).to eq( true )
524
+ end
525
+ end
526
+
527
+ it 'drift allowance can be set to zero' do
528
+ spec_helper_change_environment( 'HOODOO_CLOCK_DRIFT_TOLERANCE', '0' ) do
529
+ Hoodoo::Utilities.clear_clock_drift_configuration_cache!
530
+ expect( Hoodoo::Utilities.is_in_future?( Time.now ) ).to eq( false )
531
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + 0.1 ) ).to eq( true )
532
+ end
533
+ end
534
+
535
+ it 'drift configuration is cached' do
536
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + @default + 1 ) ).to eq( true )
537
+
538
+ # Configuring the environment variable for a much longer tolerance
539
+ # without resetting the internal cache variable should result in
540
+ # the old value still being used.
541
+ #
542
+ spec_helper_change_environment( 'HOODOO_CLOCK_DRIFT_TOLERANCE', ( @default * 2 ).to_s ) do
543
+ expect( Hoodoo::Utilities.is_in_future?( Time.now + @default + 1 ) ).to eq( true )
544
+ end
545
+ end
546
+ end
547
+
488
548
  describe '#standard_iso8601' do
489
549
  before :each do
490
550
  @old_tz = ENV[ 'TZ' ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loyalty New Zealand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-19 00:00:00.000000000 Z
11
+ date: 2018-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dalli