Testing AuthStates
This chapter will describe the best practices and ideas how to test custom AuthStates.
Unit testing
As a starting point the best approach is to write your AuthState modular. Try to keep the logic and custom code down to a minimum at your custom AuthState class and implement your business logic loosely coupled in separate classes / methods.
This way you can write simple unit test validating smaller piece of code without the need to worry about the nevisAuth engine or other systems. Ideally these test should cover most of the use-cases.
Unit testing can be done using the popular JUnit framework.
Integration testing
Users of the test framework shall consider the following constraints. Even though distributed separately, the test framework provided relies on particular Nevis rolling component versions. Due to this, if the components change, in some cases it might require a new test framework distributable. And it might also require refactoring of the already existing tests. This is the responsibility of the test framework users. Also note that several Nevis components are exposed in the test framework. This is required for the framework and test to function properly. Do not use these exposed internal endpoints and other parts to any other purpose than executing tests. Most definitely do not use them to build application logic on top of them. These are internal interfaces, and could carry breaking changes without notice due to this.
To support integration testing Nevis delivers the nevisauth-test-authstateharness-fat
artifact.
The harness is shipped as part of the SDK archive located at /opt/nevisauth/resources/nevisauth-sdk-4.x.x.x.tar.gz
Inside the archive, the harness .JAR is part of the libs
directory:
nevisauth-sdk/libs/nevisauth-test-authstateharness-fat-4.x.x.x.jar
This contains a small circle of dependencies to cover AuthState integration testing. Depending on what is the goal of the AuthState it is possible that not all dependencies are satisfied. In those cases you will most likely have to find the required jar file in the nevisAuth .rpm
package or in the .war
inside that.
Example of looking up which jar contains a certain class:
[root@localhost nevisauth]# pwd
/opt/nevisauth
[root@localhost nevisauth]# unzip /opt/nevisauth/deploy/nevisauth.war -d /opt/nevisauth/deploy/
...
[root@localhost nevisauth]# grep -ir "ch.nevis.bc.io.Severity" *
grep: deploy/WEB-INF/lib/bc-1.3.3.0.jar: binary file matches
...
Try to minimize usage of ch.nevis.\*
classes as this is a temporary solution.
Exposing yourself too much can cause higher migration efforts in the future.
The point of the artifact nevisauth-test-authstateharness-fat
is to expose the AuthStateHarness which can be used to test AuthStates on level very close to actually running nevisAuth.
Initialisation
private Properties config;
private TestContext context;
private AuthStateHarness authState;
@Before
public void setup() {
config = new Properties();
authState = new AuthStateHarness(UseridPasswordFileAuthState.class);
context = new TestContext();
}
There are 3 key figures here:
- The configuration of the AuthState (what you normally provide in the esauth4.xml)
- Context containing inargs, session information
- AuthStateHarness which allow you to execute your AuthState.
One AuthStateHarness can configure one AuthState, the idea is to test one AuthState, not an entire authentication flow with multiple AuthStates.
The AuthStateHarness by default does not configure the TokenAssembler so in case you would like to use SecTokens you can initialize that by calling the following method during your initialization: TokenAssemblerHandle.getDefaultAssembler()
Testing
Accessing the AuthContext
in the TestContext:
context.getContext().getInArgs().setProperty("username", "test");
Some utility is provided in the TestContext
so it is not always necessary to access the AuthContext
directly.
Example how to execute the AuthState:
authState.process(context);
Once the AuthState has been processed, you can execute check against the context. (containing the Session, Response, etc..)
context.assertNoError();
context.assertVariableExists(PropagationScope.NOTES, "scriptReturnValue");
context.assertVariable(PropagationScope.NOTES, "scriptReturnValue", "24");
context.assertException();
context.assertExceptionStackContains("Failed to evaluate script");
assertEquals(context.getException().getClass(), AuthStateException.class);
assertThat(EsAuth.getOutOfContextDataService().get("key"), is("value"));
Testing Debugging
In case you find that something is not working as expected you can utilize the logging of nevisAuth.
The log file will be written in the directory target/test-classes/log
.
By default the logging configuration contains many categories on debug level, however you might require to change some of those. For more, check src/test/resources/log4j2-test.yml
.
System testing
Ideally should be as close to the production system (or a part of that) as possible. Currently, Nevis doesn't offer support in System testing for custom AuthState development.