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

Environment variables on test level that are also managed by rule chains. #72

Open
jetersen opened this issue Mar 21, 2019 · 1 comment

Comments

@jetersen
Copy link

Thanks for environment variables rule.

We had some extra requirements to have greater control over environment variables, so we implemented some minor improvements with annotations.

Please see the use case here:
https://github.com/jenkinsci/configuration-as-code-plugin/pull/775/files

I have further improved the apply to allow for resolving absolute file paths.

https://github.com/jenkinsci/configuration-as-code-plugin/pull/780/files#diff-f538ae716745b68e2a599bd67bdd5dd4R22

If you feel like it is something that could be contributed back into environment variables rule! 💪
I would be happy to send a pull request 😄

@jetersen
Copy link
Author

jetersen commented Mar 21, 2019

For ease I will copy some of the code here:

Annotation usage

Converting a relative file path to an absolute file path so it can be used by the code that gets tested. ConfiguredWithCode annotation needs the ENV variables, therefore, we have a rule chain setup

    @Test
    @ConfiguredWithCode("SeedJobTest_withSecurityConfig.yml")
    @Envs(
        @Env(name = "SEED_JOB_FOLDER_FILE_PATH", value = ".")
    )
    public void configure_seed_job_with_security_config() throws Exception {
        final Jenkins jenkins = Jenkins.get();

         final GlobalJobDslSecurityConfiguration dslSecurity = GlobalConfiguration.all()
            .get(GlobalJobDslSecurityConfiguration.class);
        assertNotNull(dslSecurity);
        assertThat("ScriptSecurity", dslSecurity.isUseScriptSecurity(), is(false));

         FreeStyleProject seedJobWithSecurityConfig = (FreeStyleProject) jenkins.getItem("seedJobWithSecurityConfig");
        assertNotNull(seedJobWithSecurityConfig);

         assertTrue(seedJobWithSecurityConfig.isInQueue());
        j.buildAndAssertSuccess(seedJobWithSecurityConfig);
    }

Rule chain

    private JenkinsRule j;

    @Rule
    public RuleChain rc = RuleChain.outerRule(new EnvVarsRule()
            .set("SEED_JOB_PATH", "./src/test/resources/io/jenkins/plugins/casc/testJob2.groovy")
            .set("REPO_URL", "git://github.com/jenkinsci/configuration-as-code-plugin.git"))
            .around(j = new JenkinsConfiguredWithCodeRule());

With EnvsFromFIle we can read in secrets generated by vault 😅

    @Test
    @ConfiguredWithCode("vault.yml")
    @EnvsFromFile(VAULT_APPROLE_FILE)
    @Envs({
        @Env(name = "CASC_VAULT_PATHS", value = VAULT_PATH_KV2_1 + "," + VAULT_PATH_KV2_2),
        @Env(name = "CASC_VAULT_ENGINE_VERSION", value = "2")
    })
    public void kv2WithApprole() throws ConfiguratorException {
        assertThat(SecretSourceResolver.resolve(context, "${key1}"), equalTo("123"));
    }

The annotation work:

public class EnvVarsRule extends EnvironmentVariables {

    private Class clazz;

    private void setValue(Env env) {
        String value = env.value();
        if (env.name().endsWith("FILE_PATH")) {
            value = new File(clazz.getResource(value).getPath()).getAbsolutePath();
        }
        set(env.name(), value);
    }

    @Override
    public Statement apply(Statement base, Description description) {
        EnvsFromFile configuredWithEnvsFromFile = description.getAnnotation(EnvsFromFile.class);
        clazz = description.getTestClass();
        if (Objects.nonNull(configuredWithEnvsFromFile)) {

            final String[] resource = configuredWithEnvsFromFile.value();

            final List envFiles = Arrays.stream(resource)
                .map(s -> Paths.get(System.getProperty("java.io.tmpdir"), s).toString())
                .collect(Collectors.toList());

            Properties properties = new Properties();
            for (String file : envFiles) {
                try (FileInputStream inputStream = new FileInputStream(file)) {
                    properties.load(inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            properties.forEach((key, value) -> set(String.valueOf(key), String.valueOf(value)));
        }
        Envs configuredWithEnvs = description.getAnnotation(Envs.class);
        if (Objects.nonNull(configuredWithEnvs)) {
            List envs = Arrays.asList(configuredWithEnvs.value());
            envs.forEach(this::setValue);
        }
        return super.apply(base, description);
    }
}

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

No branches or pull requests

1 participant