Skip to content

test(parser): Default parser #315

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 6 commits into from
Jul 8, 2019
Merged

test(parser): Default parser #315

merged 6 commits into from
Jul 8, 2019

Conversation

msohailhussain
Copy link
Contributor

@msohailhussain msohailhussain commented Jul 1, 2019

Summary

Modified travis file to test all unit tests with default config parsers and default config parser is now set using ENV.
All Parsers are defined in matrix to run all unit tests with each parser.

Test plan

Unit tests should be pased

Issues

msohailhussain and others added 2 commits July 1, 2019 12:40
…zely_default_parser because picking up this var from property utils

Added unit test of default conifg parser will be usefull for travis ci env var optimizely_default_parser gets changed
@coveralls
Copy link

coveralls commented Jul 2, 2019

Pull Request Test Coverage Report for Build 1120

  • 19 of 32 (59.38%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.06%) to 89.66%

Changes Missing Coverage Covered Lines Changed/Added Lines %
core-api/src/main/java/com/optimizely/ab/config/parser/DefaultConfigParser.java 19 32 59.38%
Totals Coverage Status
Change from base Build 1111: -0.06%
Covered Lines: 3425
Relevant Lines: 3820

💛 - Coveralls

@msohailhussain msohailhussain changed the title test(parser): Default parser - Do not review - WIP test(parser): Default parser Jul 2, 2019
@msohailhussain msohailhussain requested a review from a team July 2, 2019 19:15
Copy link
Contributor

@mikecdavis mikecdavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be leveraging the enum class better to remove the redundant mappings etc that we have now. I've provided some code samples as guidance.

if (isPresent("com.fasterxml.jackson.databind.ObjectMapper")) {
String configParserName = PropertyUtils.get("default_parser");

if(configParserName != null && isPresent(configParserName)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the enum above and by assuming the configuration override is using the enum this can be cleaned up to:

        String configParserName = PropertyUtils.get("default_parser");
        if (configParserName != null) {
            try {
                ConfigParserSupplier supplier = ConfigParserSupplier.valueOf(configParserName);
                if (supplier.isPresent()) {
                    ConfigParser configParser = supplier.get();
                    logger.debug("using json parser: {}, based on override config", configParser.getClass().getSimpleName());
                    return configParser;
                }

                logger.warn("configured parser {} is not available in the classpath", configParserName);
            } catch (IllegalArgumentException e) {
                logger.warn("configured parser {} is not a valid value", configParserName);
            }
        }

.travis.yml Outdated
@@ -7,6 +7,11 @@ jdk:
install: true
addons:
srcclr: true
env:
- optimizely_default_parser=com.google.gson.Gson
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the enums here to make it clear there are a set number of supported parsers.


private final String configParserValue;

ConfigParsers(String configParserValue) {
Copy link
Contributor

@mikecdavis mikecdavis Jul 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use a supplier in the constructor and change the enum name:

    public enum ConfigParserSupplier {
        GSON_CONFIG_PARSER("com.google.gson.Gson", GsonConfigParser::new),
        JACKSON_CONFIG_PARSER("com.fasterxml.jackson.databind.ObjectMapper", JacksonConfigParser::new),
        JSON_CONFIG_PARSER("org.json.JSONObject", JsonConfigParser::new),
        JSON_SIMPLE_CONFIG_PARSER("org.json.simple.JSONObject", JsonSimpleConfigParser::new);

        private final String className;
        private final Supplier<ConfigParser> supplier;

        ConfigParserSupplier(String className, Supplier<ConfigParser> supplier) {
            this.className = className;
            this.supplier = supplier;
        }

        ConfigParser get() {
            return supplier.get();
        }

        private boolean isPresent() {
            try {
                Class.forName(className);
                return true;
            } catch (ClassNotFoundException e) {
                return false;
            }
        }
    }

Note that I moved isPresent into this enum, but not a strict requirement.

throw new MissingJsonParserException("unable to locate a JSON parser. "
+ "Please see <link> for more information");
}
} else if (isPresent("com.fasterxml.jackson.databind.ObjectMapper")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have the enum as defined above this changes from if...else if..., to:

        for (ConfigParserSupplier supplier: ConfigParserSupplier.valuesI()) {
            if (!supplier.isPresent()) {
                continue;
            }

            ConfigParser configParser = supplier.get();
            logger.info("using json parser: {}", configParser.getClass().getSimpleName());
            return configParser;
        }

        throw new MissingJsonParserException("unable to locate a JSON parser. "
            + "Please see <link> for more information");

ProjectConfig expected = validProjectConfig;
verifyProjectConfig(actual, expected);
if(defaultParser != null) {
if (DefaultConfigParser.ConfigParsers.GSON_CONFIG_PARSER.toString().equals(defaultParser)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the enum as defined earlier we can use ConfigParserSupplier.valueOf(defaultParser).

} else if (DefaultConfigParser.ConfigParsers.JSON_SIMPLE_CONFIG_PARSER.toString().equals(defaultParser)) {
Assert.assertThat(configParser, CoreMatchers.instanceOf(JsonSimpleConfigParser.class));
}
}
Copy link
Contributor

@mikecdavis mikecdavis Jul 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have an else statement defaulting to the first enum that matches? not sure if this will be deterministic however, but worth a shot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we can do that first enum that matches will be GSON_CONFIG_PARSER

@mnoman09 mnoman09 requested a review from mikecdavis July 4, 2019 15:20
Copy link
Contributor

@mikecdavis mikecdavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last change in the test case.

if(defaultParser != null) {
DefaultConfigParser.ConfigParserSupplier defaultParserSupplier = DefaultConfigParser.ConfigParserSupplier.valueOf(defaultParser);

if (DefaultConfigParser.ConfigParserSupplier.GSON_CONFIG_PARSER.equals(defaultParserSupplier)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a switch statement.

Class expectedParser = GsonConfigParser.class;

if(defaultParser != null) {
    DefaultConfigParser.ConfigParserSupplier defaultParserSupplier = DefaultConfigParser.ConfigParserSupplier.valueOf(defaultParser);
    switch (defaultParserSupplier) {
        case GSON_CONFIG_PARSER:
            expectedParser = GsonConfigParser.class;
            break;
        case JACKSON_CONFIG_PARSER:
            expectedParser = JacksonConfigParser.class;
            break;
        case JSON_CONFIG_PARSER:
            expectedParser = JsonConfigParser.class;
            break;
        case JSON_SIMPLE_CONFIG_PARSER:
            expectedParser = JsonSimpleConfigParser.class;
            break;
        default:
            fail("Not a valid config parser");
    }
}

Assert.assertThat(configParser, CoreMatchers.instanceOf(expectedParser));

@mikecdavis mikecdavis merged commit c9549cd into master Jul 8, 2019
@mikecdavis mikecdavis deleted the mnoman/setDefaultParser branch July 8, 2019 22:46
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.

4 participants