Skip to content
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

feat: add Gherking file for config #156

Merged
merged 1 commit into from
Dec 2, 2024
Merged

feat: add Gherking file for config #156

merged 1 commit into from
Dec 2, 2024

Conversation

aepfli
Copy link
Member

@aepfli aepfli commented Dec 1, 2024

I tested this with Java and Python.
With Tags we can deactivate features.
This files is not suppose to be run in an e2e env, but as a unittest for the configuration generation

Questions:

  • is java our correct implemenation? naming and type wise (why is keep alive in java a long, and everything else is a int)

java code for the whole gherkin file:

package dev.openfeature.contrib.providers.flagd.e2e.steps.config;

import dev.openfeature.contrib.providers.flagd.Config;
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;

public class ConfigSteps {

    FlagdOptions.FlagdOptionsBuilder builder = FlagdOptions.builder();
    FlagdOptions options;

    @When("we initialize a config")
    public void we_initialize_a_config() {
        options = builder.build();
    }

    @When("we initialize a config for {string}")
    public void we_initialize_a_config_for(String string) {
        switch (string.toLowerCase()) {
            case "in-process":
                options = builder.resolverType(Config.Resolver.IN_PROCESS).build();
                break;
            case "rpc":
                options = builder.resolverType(Config.Resolver.RPC).build();
                break;
            default:
                throw new RuntimeException("Unknown resolver type: " + string);
        }
    }

    @When("we have an option {string} of type {string} with value {string}")
    public void we_have_an_option_of_type_with_value(String option, String type, String value) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Object converted = convert(value, type);
        Method method = Arrays.stream(builder.getClass().getMethods())
                .filter(method1 -> method1.getName().equals(option))
                .findFirst()
                .orElseThrow(RuntimeException::new);
        method.invoke(builder, converted);
    }


    Map<String, String> envVarsSet = new HashMap<>();

    @When("we have an environment variable {string} with value {string}")
    public void we_have_an_environment_variable_with_value(String string, String string2) throws IllegalAccessException, NoSuchFieldException {
        String getenv = System.getenv(string);
        envVarsSet.put(string, getenv);
        EnvironmentVariableUtils.set(string, string2);
    }

    private Object convert(String value, String type) throws ClassNotFoundException {
        if (Objects.equals(value, "null")) return null;
        switch (type) {
            case "Boolean":
                return Boolean.parseBoolean(value);
            case "String":
                return value;
            case "Integer":
                return Integer.parseInt(value);
            case "Long":
                return Long.parseLong(value);
            case "ResolverType":
                switch (value.toLowerCase()) {
                    case "in-process":
                        return Config.Resolver.IN_PROCESS;
                    case "rpc":
                        return Config.Resolver.RPC;
                    default:
                        throw new RuntimeException("Unknown resolver type: " + value);
                }
            case "CacheType":
                return CacheType.valueOf(value.toUpperCase()).getValue();
        }
        throw new RuntimeException("Unknown config type: " + type);
    }

    @Then("the option {string} of type {string} should have the value {string}")
    public void the_option_of_type_should_have_the_value(String option, String type, String value) throws Throwable {
        Object convert = convert(value, type);

        assertThat(options).hasFieldOrPropertyWithValue(option, convert);

        // Resetting env vars
        for (Map.Entry<String, String> envVar : envVarsSet.entrySet()) {
            if (envVar.getValue() == null) {
                EnvironmentVariableUtils.clear(envVar.getKey());
            } else {
                EnvironmentVariableUtils.set(envVar.getKey(), envVar.getValue());
            }
        }
    }
}

@aepfli aepfli force-pushed the feat/gherkin_for_config branch 3 times, most recently from 18070b6 to 8b59fcd Compare December 1, 2024 15:14
I tested this with Java and Python.
With Tags we can deactivate features.
This files is not suppose to be run in an e2e env,
but as a unittest for the configuration generation

Signed-off-by: Simon Schrottner <[email protected]>
@aepfli aepfli force-pushed the feat/gherkin_for_config branch from 8b59fcd to f997c9f Compare December 1, 2024 15:51
@aepfli
Copy link
Member Author

aepfli commented Dec 1, 2024

with this file, i found already some problems within the python implementation, eg upper case lower case problems with the ResolverType (will add verification for the cacheType too)

@aepfli
Copy link
Member Author

aepfli commented Dec 1, 2024

i would also add


      | option       | env                  | type      | value    |
      | cacheType    | FLAGD_CACHE          | CacheType | lru |
      | cacheType    | FLAGD_CACHE          | CacheType | disabled |
      | cacheType    | FLAGD_CACHE          | CacheType | LRU      |
      | cacheType    | FLAGD_CACHE          | CacheType | DISABLED |

but this breaks also in java - whereas we support different writings for the resolver type :)

@aepfli aepfli merged commit fe9c3c8 into main Dec 2, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants