From 6a8ddbf3dec8e69720b394c6abc644ff62fd9e5f Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Mon, 22 Jun 2026 21:17:03 -0400 Subject: [PATCH] Enable Ruby OpenFeature tests on older weblog --- manifests/ruby.yml | 2 + utils/build/docker/ruby/sinatra41/Gemfile | 1 + .../build/docker/ruby/sinatra41/Gemfile.lock | 13 ++++ utils/build/docker/ruby/sinatra41/app.rb | 63 +++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/manifests/ruby.yml b/manifests/ruby.yml index 42e95e0819d..750e01f6615 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -1882,7 +1882,9 @@ manifest: tests/ffe/test_dynamic_evaluation.py: - weblog_declaration: "*": irrelevant + uds-sinatra: v2.24.0 rails72: v2.23.0-dev + sinatra41: v2.24.0 tests/ffe/test_exposures.py: - weblog_declaration: "*": irrelevant diff --git a/utils/build/docker/ruby/sinatra41/Gemfile b/utils/build/docker/ruby/sinatra41/Gemfile index 789eaa71a55..aabb54e3d46 100644 --- a/utils/build/docker/ruby/sinatra41/Gemfile +++ b/utils/build/docker/ruby/sinatra41/Gemfile @@ -13,4 +13,5 @@ end gem 'dogstatsd-ruby' gem 'pg' +gem 'openfeature-sdk', '~> 0.5.1' gem 'datadog', '~> 2.0', require: 'datadog/auto_instrument' diff --git a/utils/build/docker/ruby/sinatra41/Gemfile.lock b/utils/build/docker/ruby/sinatra41/Gemfile.lock index 8bafb273d98..bb3b24266da 100644 --- a/utils/build/docker/ruby/sinatra41/Gemfile.lock +++ b/utils/build/docker/ruby/sinatra41/Gemfile.lock @@ -16,6 +16,8 @@ GEM faraday-net_http (>= 2.0, < 3.5) json logger + faraday-follow_redirects (0.5.0) + faraday (>= 1, < 3) faraday-net_http (3.4.1) net-http (>= 0.5.0) ffi (1.17.2) @@ -58,6 +60,14 @@ GEM net-http (0.6.0) uri nio4r (2.7.4) + openfeature-sdk (0.5.1) + pg (1.6.3) + pg (1.6.3-aarch64-linux) + pg (1.6.3-aarch64-linux-musl) + pg (1.6.3-arm64-darwin) + pg (1.6.3-x86_64-darwin) + pg (1.6.3-x86_64-linux) + pg (1.6.3-x86_64-linux-musl) pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) @@ -111,6 +121,9 @@ DEPENDENCIES datadog (~> 2.0) dogstatsd-ruby faraday + faraday-follow_redirects (~> 0.3) + openfeature-sdk (~> 0.5.1) + pg pry-byebug puma (~> 6.0) rack-contrib diff --git a/utils/build/docker/ruby/sinatra41/app.rb b/utils/build/docker/ruby/sinatra41/app.rb index 81cced11370..8d847176ba7 100644 --- a/utils/build/docker/ruby/sinatra41/app.rb +++ b/utils/build/docker/ruby/sinatra41/app.rb @@ -6,6 +6,8 @@ require 'faraday/follow_redirects' require 'sinatra/json' require 'pg' +require 'open_feature/sdk' +require 'datadog/open_feature/provider' begin require 'datadog/auto_instrument' @@ -20,6 +22,10 @@ c.use :sinatra, service_name: ENV.fetch('DD_SERVICE', 'sinatra') unless c.respond_to?(:tracing) end +OpenFeature::SDK.configure do |config| + config.set_provider(Datadog::OpenFeature::Provider.new) +end + require 'rack/contrib/json_body_parser' use Rack::JSONBodyParser @@ -58,6 +64,63 @@ 'Hello, world!' end +post '/ffe/start' do + OpenFeature::SDK.set_provider(Datadog::OpenFeature::Provider.new) + + loop do + break unless Datadog::OpenFeature.evaluator.ufc_json.nil? + sleep 0.1 + end + + content_type :json + {}.to_json +end + +post '/ffe' do + client = OpenFeature::SDK.build_client + payload = JSON.parse(request.body.read) + + targeting_keys = + if payload['targetingKeys'].is_a?(Array) && !payload['targetingKeys'].empty? + payload['targetingKeys'] + else + [payload['targetingKey']] + end + + value = nil + targeting_keys.each do |targeting_key| + context = OpenFeature::SDK::EvaluationContext.new( + targeting_key: targeting_key, + **(payload['attributes'] || {}) + ) + options = { + flag_key: payload['flag'], + default_value: payload['defaultValue'], + evaluation_context: context + } + + value = + case payload['variationType'] + when 'BOOLEAN' then client.fetch_boolean_value(**options) + when 'STRING' then client.fetch_string_value(**options) + when 'INTEGER' then client.fetch_integer_value(**options) + when 'NUMERIC' then client.fetch_float_value(**options) + when 'JSON' then client.fetch_object_value(**options) + else 'FATAL_UNEXPECTED_VARIATION_TYPE' + end + end + + content_type :json + {value: value, reason: 'DEFAULT', count: targeting_keys.length}.to_json +rescue + content_type :json + {value: payload && payload['defaultValue'], reason: 'ERROR'}.to_json +end + +post '/ffe/evaluate' do + call env.merge('PATH_INFO' => '/ffe') +end + get '/waf' do 'Hello, world!' end