flipper 1.2.2 → 1.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -1
  3. data/.github/workflows/examples.yml +1 -1
  4. data/README.md +2 -0
  5. data/docs/images/banner.jpg +0 -0
  6. data/lib/flipper/adapters/actor_limit.rb +28 -0
  7. data/lib/flipper/adapters/cache_base.rb +143 -0
  8. data/lib/flipper/adapters/operation_logger.rb +18 -88
  9. data/lib/flipper/adapters/read_only.rb +6 -39
  10. data/lib/flipper/adapters/strict.rb +5 -10
  11. data/lib/flipper/adapters/wrapper.rb +54 -0
  12. data/lib/flipper/cli.rb +36 -17
  13. data/lib/flipper/cloud/configuration.rb +2 -3
  14. data/lib/flipper/cloud/telemetry/instrumenter.rb +4 -8
  15. data/lib/flipper/cloud/telemetry.rb +10 -2
  16. data/lib/flipper/engine.rb +5 -5
  17. data/lib/flipper/poller.rb +6 -5
  18. data/lib/flipper/serializers/gzip.rb +3 -5
  19. data/lib/flipper/serializers/json.rb +3 -5
  20. data/lib/flipper/spec/shared_adapter_specs.rb +17 -16
  21. data/lib/flipper/test/shared_adapter_test.rb +17 -17
  22. data/lib/flipper/typecast.rb +3 -3
  23. data/lib/flipper/version.rb +1 -1
  24. data/lib/flipper.rb +3 -1
  25. data/package-lock.json +41 -0
  26. data/package.json +10 -0
  27. data/spec/flipper/adapters/actor_limit_spec.rb +20 -0
  28. data/spec/flipper/adapters/http_spec.rb +11 -2
  29. data/spec/flipper/cli_spec.rb +21 -46
  30. data/spec/flipper/cloud/configuration_spec.rb +2 -1
  31. data/spec/flipper/cloud/telemetry_spec.rb +52 -0
  32. data/spec/flipper/cloud_spec.rb +4 -2
  33. data/spec/flipper/engine_spec.rb +34 -4
  34. data/spec/flipper/middleware/memoizer_spec.rb +7 -4
  35. data/spec/support/fail_on_output.rb +8 -0
  36. data/spec/support/spec_helpers.rb +2 -1
  37. data/test/adapters/actor_limit_test.rb +20 -0
  38. data/test_rails/system/test_help_test.rb +1 -1
  39. metadata +14 -3
@@ -4,8 +4,10 @@ require 'flipper/engine'
4
4
  RSpec.describe Flipper::Engine do
5
5
  let(:application) do
6
6
  Class.new(Rails::Application) do
7
+ config.load_defaults Rails::VERSION::STRING.to_f
7
8
  config.eager_load = false
8
9
  config.logger = ActiveSupport::Logger.new($stdout)
10
+ config.active_support.remove_deprecated_time_with_zone_name = false
9
11
  end.instance
10
12
  end
11
13
 
@@ -51,7 +53,7 @@ RSpec.describe Flipper::Engine do
51
53
  ENV['FLIPPER_STRICT'] = 'false'
52
54
  subject
53
55
  expect(config.strict).to eq(false)
54
- expect(adapter).to be_instance_of(Flipper::Adapters::Memory)
56
+ expect(adapter).not_to be_instance_of(Flipper::Adapters::Strict)
55
57
  end
56
58
 
57
59
  [true, :raise, :warn].each do |value|
@@ -67,7 +69,7 @@ RSpec.describe Flipper::Engine do
67
69
  initializer { config.strict = false }
68
70
  subject
69
71
  expect(config.strict).to eq(false)
70
- expect(adapter).to be_instance_of(Flipper::Adapters::Memory)
72
+ expect(adapter).not_to be_instance_of(Flipper::Adapters::Strict)
71
73
  end
72
74
 
73
75
  it "defaults to strict=:warn in RAILS_ENV=development" do
@@ -83,7 +85,7 @@ RSpec.describe Flipper::Engine do
83
85
  expect(Rails.env).to eq(env)
84
86
  subject
85
87
  expect(config.strict).to eq(false)
86
- expect(adapter).to be_instance_of(Flipper::Adapters::Memory)
88
+ expect(adapter).not_to be_instance_of(Flipper::Adapters::Strict)
87
89
  end
88
90
  end
89
91
 
@@ -234,7 +236,8 @@ RSpec.describe Flipper::Engine do
234
236
  application.initialize!
235
237
 
236
238
  expect(Flipper.instance).to be_a(Flipper::Cloud::DSL)
237
- expect(Flipper.instance.instrumenter).to be(ActiveSupport::Notifications)
239
+ expect(Flipper.instance.instrumenter).to be_a(Flipper::Cloud::Telemetry::Instrumenter)
240
+ expect(Flipper.instance.instrumenter.instrumenter).to be(ActiveSupport::Notifications)
238
241
  end
239
242
 
240
243
  context "with CLOUD_SYNC_SECRET" do
@@ -334,6 +337,33 @@ RSpec.describe Flipper::Engine do
334
337
  expect(ActiveRecord::Base.ancestors).to include(Flipper::Model::ActiveRecord)
335
338
  end
336
339
 
340
+ describe "config.actor_limit" do
341
+ let(:adapter) do
342
+ application.initialize!
343
+ Flipper.adapter.adapter.adapter
344
+ end
345
+
346
+ it "defaults to 100" do
347
+ expect(adapter).to be_instance_of(Flipper::Adapters::ActorLimit)
348
+ expect(adapter.limit).to eq(100)
349
+ end
350
+
351
+ it "can be set from FLIPPER_ACTOR_LIMIT env" do
352
+ ENV["FLIPPER_ACTOR_LIMIT"] = "500"
353
+ expect(adapter.limit).to eq(500)
354
+ end
355
+
356
+ it "can be set from an initializer" do
357
+ initializer { config.actor_limit = 99 }
358
+ expect(adapter.limit).to eq(99)
359
+ end
360
+
361
+ it "can be disabled from an initializer" do
362
+ initializer { config.actor_limit = false }
363
+ expect(adapter).not_to be_instance_of(Flipper::Adapters::ActorLimit)
364
+ end
365
+ end
366
+
337
367
  # Add app initializer in the same order as config/initializers/*
338
368
  def initializer(&block)
339
369
  application.initializer 'spec', before: :load_config_initializers do
@@ -458,7 +458,7 @@ RSpec.describe Flipper::Middleware::Memoizer do
458
458
  logged_memory = Flipper::Adapters::OperationLogger.new(memory)
459
459
  cache = ActiveSupport::Cache::MemoryStore.new
460
460
  cache.clear
461
- cached = Flipper::Adapters::ActiveSupportCacheStore.new(logged_memory, cache, expires_in: 10)
461
+ cached = Flipper::Adapters::ActiveSupportCacheStore.new(logged_memory, cache)
462
462
  logged_cached = Flipper::Adapters::OperationLogger.new(cached)
463
463
  memo = {}
464
464
  flipper = Flipper.new(logged_cached)
@@ -471,15 +471,18 @@ RSpec.describe Flipper::Middleware::Memoizer do
471
471
 
472
472
  get '/', {}, 'flipper' => flipper
473
473
  expect(logged_cached.count(:get_all)).to be(1)
474
- expect(logged_memory.count(:get_all)).to be(1)
474
+ expect(logged_memory.count(:features)).to be(1)
475
+ expect(logged_memory.count(:get_multi)).to be(1)
475
476
 
476
477
  get '/', {}, 'flipper' => flipper
477
478
  expect(logged_cached.count(:get_all)).to be(2)
478
- expect(logged_memory.count(:get_all)).to be(1)
479
+ expect(logged_memory.count(:features)).to be(1)
480
+ expect(logged_memory.count(:get_multi)).to be(1)
479
481
 
480
482
  get '/', {}, 'flipper' => flipper
481
483
  expect(logged_cached.count(:get_all)).to be(3)
482
- expect(logged_memory.count(:get_all)).to be(1)
484
+ expect(logged_memory.count(:features)).to be(1)
485
+ expect(logged_memory.count(:get_multi)).to be(1)
483
486
  end
484
487
  end
485
488
  end
@@ -0,0 +1,8 @@
1
+ if ENV["CI"] || ENV["FAIL_ON_OUTPUT"]
2
+ RSpec.configure do |config|
3
+ config.around do |example|
4
+ output = silence { example.run }
5
+ fail "Use `silence { }` to avoid printing to STDOUT/STDERR\n#{output}" unless output.empty?
6
+ end
7
+ end
8
+ end
@@ -1,6 +1,7 @@
1
1
  require 'ice_age'
2
2
  require 'json'
3
3
  require 'rack/test'
4
+ require 'rack/session'
4
5
 
5
6
  module SpecHelpers
6
7
  extend self
@@ -12,7 +13,7 @@ module SpecHelpers
12
13
 
13
14
  def build_app(flipper, options = {})
14
15
  Flipper::UI.app(flipper, options) do |builder|
15
- builder.use Rack::Session::Cookie, secret: 'test'
16
+ builder.use Rack::Session::Cookie, secret: 'test' * 16 # Rack 3+ wants a 64-character secret
16
17
  end
17
18
  end
18
19
 
@@ -0,0 +1,20 @@
1
+ require "test_helper"
2
+ require "flipper/test/shared_adapter_test"
3
+ require "flipper/adapters/actor_limit"
4
+
5
+ class Flipper::Adapters::ActorLimitTest < MiniTest::Test
6
+ prepend Flipper::Test::SharedAdapterTests
7
+
8
+ def setup
9
+ @memory = Flipper::Adapters::Memory.new
10
+ @adapter = Flipper::Adapters::ActorLimit.new(@memory, 5)
11
+ end
12
+
13
+ def test_enable_fails_when_limit_exceeded
14
+ 5.times { |i| @feature.enable Flipper::Actor.new("User;#{i}") }
15
+
16
+ assert_raises Flipper::Adapters::ActorLimit::LimitExceeded do
17
+ @feature.enable Flipper::Actor.new("User;6")
18
+ end
19
+ end
20
+ end
@@ -29,7 +29,7 @@ end
29
29
 
30
30
  class TestHelpTest < ActionDispatch::SystemTestCase
31
31
  # Any driver that runs the app in a separate thread will test what we want here.
32
- driven_by :cuprite, options: { process_timeout: 30 }
32
+ driven_by :cuprite, options: { process_timeout: 60 }
33
33
 
34
34
  setup do
35
35
  # Reconfigure Flipper since other tests change the adapter.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-19 00:00:00.000000000 Z
11
+ date: 2024-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -90,6 +90,8 @@ files:
90
90
  - lib/flipper/actor.rb
91
91
  - lib/flipper/adapter.rb
92
92
  - lib/flipper/adapter_builder.rb
93
+ - lib/flipper/adapters/actor_limit.rb
94
+ - lib/flipper/adapters/cache_base.rb
93
95
  - lib/flipper/adapters/dual_write.rb
94
96
  - lib/flipper/adapters/failover.rb
95
97
  - lib/flipper/adapters/failsafe.rb
@@ -109,6 +111,7 @@ files:
109
111
  - lib/flipper/adapters/sync/feature_synchronizer.rb
110
112
  - lib/flipper/adapters/sync/interval_synchronizer.rb
111
113
  - lib/flipper/adapters/sync/synchronizer.rb
114
+ - lib/flipper/adapters/wrapper.rb
112
115
  - lib/flipper/cli.rb
113
116
  - lib/flipper/cloud.rb
114
117
  - lib/flipper/cloud/configuration.rb
@@ -193,12 +196,15 @@ files:
193
196
  - lib/generators/flipper/templates/update/migrations/01_create_flipper_tables.rb.erb
194
197
  - lib/generators/flipper/templates/update/migrations/02_change_flipper_gates_value_to_text.rb.erb
195
198
  - lib/generators/flipper/update_generator.rb
199
+ - package-lock.json
200
+ - package.json
196
201
  - spec/fixtures/environment.rb
197
202
  - spec/fixtures/feature.json
198
203
  - spec/fixtures/flipper_pstore_1679087600.json
199
204
  - spec/flipper/actor_spec.rb
200
205
  - spec/flipper/adapter_builder_spec.rb
201
206
  - spec/flipper/adapter_spec.rb
207
+ - spec/flipper/adapters/actor_limit_spec.rb
202
208
  - spec/flipper/adapters/dual_write_spec.rb
203
209
  - spec/flipper/adapters/failover_spec.rb
204
210
  - spec/flipper/adapters/failsafe_spec.rb
@@ -287,10 +293,12 @@ files:
287
293
  - spec/spec_helper.rb
288
294
  - spec/support/actor_names.yml
289
295
  - spec/support/descriptions.yml
296
+ - spec/support/fail_on_output.rb
290
297
  - spec/support/fake_backoff_policy.rb
291
298
  - spec/support/fake_udp_socket.rb
292
299
  - spec/support/skippable.rb
293
300
  - spec/support/spec_helpers.rb
301
+ - test/adapters/actor_limit_test.rb
294
302
  - test/adapters/memory_test.rb
295
303
  - test/adapters/pstore_test.rb
296
304
  - test/test_helper.rb
@@ -306,7 +314,7 @@ metadata:
306
314
  homepage_uri: https://www.flippercloud.io
307
315
  source_code_uri: https://github.com/flippercloud/flipper
308
316
  bug_tracker_uri: https://github.com/flippercloud/flipper/issues
309
- changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.2.2
317
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.0
310
318
  post_install_message:
311
319
  rdoc_options: []
312
320
  require_paths:
@@ -333,6 +341,7 @@ test_files:
333
341
  - spec/flipper/actor_spec.rb
334
342
  - spec/flipper/adapter_builder_spec.rb
335
343
  - spec/flipper/adapter_spec.rb
344
+ - spec/flipper/adapters/actor_limit_spec.rb
336
345
  - spec/flipper/adapters/dual_write_spec.rb
337
346
  - spec/flipper/adapters/failover_spec.rb
338
347
  - spec/flipper/adapters/failsafe_spec.rb
@@ -421,10 +430,12 @@ test_files:
421
430
  - spec/spec_helper.rb
422
431
  - spec/support/actor_names.yml
423
432
  - spec/support/descriptions.yml
433
+ - spec/support/fail_on_output.rb
424
434
  - spec/support/fake_backoff_policy.rb
425
435
  - spec/support/fake_udp_socket.rb
426
436
  - spec/support/skippable.rb
427
437
  - spec/support/spec_helpers.rb
438
+ - test/adapters/actor_limit_test.rb
428
439
  - test/adapters/memory_test.rb
429
440
  - test/adapters/pstore_test.rb
430
441
  - test/test_helper.rb