-
Notifications
You must be signed in to change notification settings - Fork 13
chore: add e2e test suite #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| [submodule "providers/openfeature-flagd-provider/schemas"] | ||
| path = providers/openfeature-flagd-provider/schemas | ||
| url = https://github.com/open-feature/flagd-schemas | ||
| [submodule "providers/openfeature-flagd-provider/test-harness"] | ||
| path = providers/openfeature-flagd-provider/test-harness | ||
| url = https://github.com/open-feature/flagd-testbed.git |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| default: --require features --publish-quiet --tags "not @deprecated and not @no-default-variant and not @fractional-v1 and not @fractional-v3" test-harness/gherkin/evaluation.feature test-harness/gherkin/targeting.feature |
80 changes: 80 additions & 0 deletions
80
providers/openfeature-flagd-provider/features/step_definitions/flagd_steps.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "json" | ||
|
|
||
| module StepHelpers | ||
| def cast(type, value) | ||
| case type | ||
| when "Boolean" then value == "true" | ||
| when "Integer" then value.to_i | ||
| when "Float" then value.to_f | ||
| when "Object" then JSON.parse(value) | ||
| else value | ||
| end | ||
| end | ||
|
|
||
| # flagd returns object values as a protobuf Struct; normalise to a Hash for comparison. | ||
| def unwrap(value) | ||
| value.respond_to?(:to_h) ? value.to_h : value | ||
| end | ||
| end | ||
| World(StepHelpers) | ||
|
|
||
| Given(/^an option "[^"]*" of type "[^"]*" with value "[^"]*"$/) do | ||
| # no-op: caching/streaming options aren't applicable here | ||
| end | ||
|
|
||
| Given(/^a stable flagd provider$/) do | ||
| @client = OpenFeature::Flagd::Provider.build_client | ||
| @context = {} | ||
| end | ||
|
|
||
| Given(/^a (\w+)-flag with key "([^"]*)" and a default value "([^"]*)"$/) do |type, key, default| | ||
| @type = type | ||
| @key = key | ||
| @default = default | ||
| end | ||
|
|
||
| Given(/^a context containing a key "([^"]*)", with type "([^"]*)" and with value "([^"]*)"$/) do |key, type, value| | ||
| @context[key] = cast(type, value) | ||
| end | ||
|
|
||
| Given(/^a context containing a targeting key with value "([^"]*)"$/) do |value| | ||
| # the provider maps the "targeting_key" field to flagd's targetingKey | ||
| @context["targeting_key"] = value | ||
| end | ||
|
|
||
| Given(/^a context containing a nested property with outer key "([^"]*)" and inner key "([^"]*)", with value "([^"]*)"$/) do |outer, inner, value| | ||
| (@context[outer] ||= {})[inner] = value | ||
| end | ||
|
|
||
| When(/^the flag was evaluated with details$/) do | ||
| ctx = @context.empty? ? nil : OpenFeature::SDK::EvaluationContext.new(**@context.transform_keys(&:to_sym)) | ||
|
|
||
| @details = | ||
| case @type | ||
| when "Boolean" then @client.fetch_boolean_value(flag_key: @key, default_value: cast("Boolean", @default), evaluation_context: ctx) | ||
| when "String" then @client.fetch_string_value(flag_key: @key, default_value: @default, evaluation_context: ctx) | ||
| when "Integer" then @client.fetch_integer_value(flag_key: @key, default_value: @default.to_i, evaluation_context: ctx) | ||
| when "Float" then @client.fetch_float_value(flag_key: @key, default_value: @default.to_f, evaluation_context: ctx) | ||
| when "Object" then @client.fetch_object_value(flag_key: @key, default_value: cast("Object", @default), evaluation_context: ctx) | ||
| else raise "unsupported flag type: #{@type}" | ||
| end | ||
| end | ||
|
|
||
| Then(/^the resolved details value should be "([^"]*)"$/) do |value| | ||
| actual = (@type == "Object") ? unwrap(@details[:value]) : @details[:value] | ||
| expect(actual).to eq(cast(@type, value)) | ||
| end | ||
|
|
||
| Then(/^the reason should be "([^"]*)"$/) do |reason| | ||
| expect(@details[:reason]).to eq(reason) | ||
| end | ||
|
|
||
| Then(/^the error-code should be "([^"]*)"$/) do |code| | ||
| if code.empty? | ||
| expect(@details[:error_code]).to be_nil | ||
| else | ||
| expect(@details[:error_code]).to eq(code) | ||
| end | ||
| end |
64 changes: 64 additions & 0 deletions
64
providers/openfeature-flagd-provider/features/support/env.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "net/http" | ||
| require "uri" | ||
| require "rspec/expectations" | ||
| require "open_feature/sdk" | ||
| require "openfeature/flagd/provider" | ||
|
|
||
| World(RSpec::Matchers) | ||
|
|
||
| # Boots the shared flagd testbed container and drives its launchpad so flagd is serving the | ||
| # standard flag set before the suite runs. Uses the Docker CLI directly (reliable on CI). | ||
| module Testbed | ||
| VERSION = File.read(File.expand_path("../../test-harness/version.txt", __dir__)).strip | ||
| IMAGE = "ghcr.io/open-feature/flagd-testbed:v#{VERSION}" | ||
| NAME = "flagd-e2e-ruby-#{Process.pid}" | ||
|
|
||
| module_function | ||
|
|
||
| def start | ||
| sh("docker rm -f #{NAME}") | ||
| raise "failed to start #{IMAGE} (is docker available?)" unless | ||
| sh("docker run -d --name #{NAME} -p 8013:8013 -p 8014:8014 -p 8080:8080 #{IMAGE}") | ||
|
|
||
| # launchpad starts flagd with the default flag set | ||
| wait_for { http_code(:post, "http://localhost:8080/start") } | ||
| wait_for { http_code(:get, "http://localhost:8014/healthz") == "200" } || | ||
| raise("flagd testbed did not become healthy in time") | ||
| end | ||
|
|
||
| def stop | ||
| sh("docker rm -f #{NAME}") | ||
| end | ||
|
|
||
| def sh(cmd) | ||
| system(cmd, out: File::NULL, err: File::NULL) | ||
| end | ||
|
|
||
| def http_code(verb, url) | ||
| uri = URI(url) | ||
| res = if verb == :post | ||
| Net::HTTP.post(uri, "") | ||
| else | ||
| Net::HTTP.get_response(uri) | ||
| end | ||
| res.code | ||
| rescue | ||
| nil | ||
| end | ||
|
|
||
| def wait_for(timeout: 60) | ||
| deadline = Time.now + timeout | ||
| loop do | ||
| return true if yield | ||
| return false if Time.now > deadline | ||
|
|
||
| sleep 0.5 | ||
| end | ||
| end | ||
| end | ||
|
|
||
| # register teardown before startup so a container is cleaned up even if start raises | ||
| at_exit { Testbed.stop } | ||
| Testbed.start |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule test-harness
added at
6dea1d
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: open-feature/ruby-sdk-contrib
Length of output: 16521
🌐 Web query:
actions/checkout v7 README persist-credentials default submodules recursive💡 Result:
In
actions/checkoutv7, the default behaviors forpersist-credentialsandsubmodulesare as follows: - persist-credentials: The default value istrue[1][2][3][4]. When enabled, the Git authentication token is persisted in the local Git configuration, allowing subsequent steps in the workflow to perform authenticated Git commands. This token is automatically removed during the post-job cleanup [1][2][5]. To opt-out of this behavior, you must explicitly setpersist-credentials: false[1][2]. - submodules: The default value isfalse[3][4]. This input determines whether to checkout submodules; it can be set totrueto checkout submodules orrecursiveto perform a recursive checkout of submodules [3][4]. The v7 release primarily introduced security improvements, such as blocking the checkout of fork pull request code inpull_request_targetandworkflow_runworkflows when using insecure inputs [6].Citations:
Disable persisted checkout credentials before running tests.
This
pull_requestworkflow executes checked-out code with acontents: readGITHUB_TOKEN.actions/checkout@v7persists that token in local Git configuration by default. Untrusted pull request code can use it for authenticated repository access. Setpersist-credentials: false. Confirm that private submodule access still works if required.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 61-63: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Source: Linters/SAST tools