Skip to content

Commit

Permalink
Add tests with enabled SecurityManager to env extension (#241 / #242)
Browse files Browse the repository at this point in the history
The documentation mentions that without proper permissions an enabled
security manager will not give access to the internals we need to
change environment variables. These tests confirm that.

Closes: #241
PR: #242
  • Loading branch information
Hancho2009 committed Jul 14, 2020
1 parent c869d7b commit bc4d50b
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 7 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ The least we can do is to thank them and list their accomplishments here (in lex

* [Allon Murienik](https://github.com/mureinik) contributed [the range sources](https://junit-pioneer.org/docs/range-sources/) (#44 / #123)
* [Daniel Kraus](https://github.com/beatngu13) contributed [the system property extension](https://junit-pioneer.org/docs/system-properties/) (#129 / #133), further improved it as well as the environment variable extension (#180 / #248), and helped with build infrastructure (e.g. #269)
* [Dirk Witzel](https://github.com/NPException) improved the documentation (#149 / #271)
* [Dirk Witzel](https://github.com/NPException) improved the documentation (#149 / #271)
* [Ignat Simonenko](https://github.com/simonenkoi) fixed a noteworthy bug in the default locale extension (#146 / #161)
* [Mark Rösler](https://github.com/Hancho2009) contributed the [environment variable extension](https://junit-pioneer.org/docs/environment-variables/) (#167 / #174)
* [Mark Rösler](https://github.com/Hancho2009) contributed the [environment variable extension](https://junit-pioneer.org/docs/environment-variables/) (#167 / #174 and #241 / #242)
* [Matthias Bünger](https://github.com/Bukama) opened, vetted, and groomed countless issues and PRs and contributed multiple refactorings (e.g. #165 / #168) and fixes (e.g. #190 / #200) before getting promoted to maintainer
* [Mihály Verhás](https://github.com/Michael1993) contributed [the StdIO extension](https://junit-pioneer.org/docs/standard-input-output/) (#34 / #227), added tests to other extensions (#164 / #272), and commented on multiple issues and PRs
* [Nishant Vashisth](https://github.com/nishantvas) contributed an [extension to disable parameterized tests](https://junit-pioneer.org/docs/disable-if-display-name/) by display name (#163 / #175)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@

package org.junitpioneer.jupiter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.security.AccessControlException;
import java.security.Policy;
import java.util.HashMap;
import java.util.Map;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

@DisplayName("JUnitPioneer system environment utilities")
Expand All @@ -25,11 +30,56 @@ class EnvironmentVariableUtilsTests {
void theEnvironmentIsNotCorruptedAfterSet() {
EnvironmentVariableUtils.set("A_VARIABLE", "A value");

// By using this method, the entire environment is read and copied from the field
// ProcessEnvironment.theEnvironment. If that field is corrupted by a String having been stored
// as key or value, this copy operation will fail with a ClassCastException.
/* By using this method, the entire environment is read and copied from the field
ProcessEnvironment.theEnvironment. If that field is corrupted by a String having been stored
as key or value, this copy operation will fail with a ClassCastException. */
Map<String, String> environmentCopy = new HashMap<>(System.getenv());
assertEquals("A value", environmentCopy.get("A_VARIABLE"));
assertThat(environmentCopy.get("A_VARIABLE")).isEqualTo("A value");
}

/*
* The documentation mentions that without proper permissions an enabled security manager will not
* give access to the internals we need to change environment variables. These tests confirm that.
*/
@ClearEnvironmentVariable(key = "TEST")
@Nested
class With_SecurityManager {

@Test
@SetSystemProperty(key = "java.security.policy", value = "file:src/test/resources/default-testing.policy")
void shouldThrowAccessControlExceptionWithDefaultSecurityManager() {
//@formatter:off
executeWithSecurityManager(
() -> assertThatThrownBy(() -> EnvironmentVariableUtils.set("TEST", "TEST"))
.isInstanceOf(AccessControlException.class));
//@formatter:on
}

@Test
@SetSystemProperty(key = "java.security.policy", value = "file:src/test/resources/reflect-permission-testing.policy")
void shouldModifyEnvironmentVariableIfPermissionIsGiven() {
executeWithSecurityManager(() -> {
assertThatCode(() -> EnvironmentVariableUtils.set("TEST", "TEST")).doesNotThrowAnyException();
assertThat(System.getenv("TEST")).isEqualTo("TEST");
});
}

/*
* This needs to be done during the execution of the test method and cannot be moved to setup/tear down
* because junit uses reflection and the default SecurityManager prevents that.
*/
private void executeWithSecurityManager(Runnable runnable) {
Policy.getPolicy().refresh();
final SecurityManager original = System.getSecurityManager();
System.setSecurityManager(new SecurityManager());
try {
runnable.run();
}
finally {
System.setSecurityManager(original);
}
}

}

}
7 changes: 7 additions & 0 deletions src/test/resources/default-testing.policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
grant {
// allow to reset the SecurityManager after the unit test
permission java.lang.RuntimePermission "setSecurityManager";

// necessary for gradle
permission javax.management.MBeanServerPermission "createMBeanServer";
};
17 changes: 17 additions & 0 deletions src/test/resources/reflect-permission-testing.policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
grant {
// allow to reset the SecurityManager after the unit test
permission java.lang.RuntimePermission "setSecurityManager";

// necessary for gradle
permission javax.management.MBeanServerPermission "createMBeanServer";

// needed for EnvironmentVariableUtilsTests#shouldModifyEnvironmentVariableIfPermissionIsGiven
permission java.lang.RuntimePermission "getenv.*";

// needed for assertj
permission java.util.logging.LoggingPermission "control";

// needed for EnvironmentVariableUtils
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

0 comments on commit bc4d50b

Please sign in to comment.