Authorisation token expires too soon
I'm running data-driven tests that have 5 steps:
- 1. Get new Authorisation token
- 2. DataSource (get a few thousand random rows from DB2)
- 3. REST Request
- 4. Assert script
- 5. DataSource Loop
The problem is that the Authorisation token expires after say 30 seconds, so if I increase the number of rows in my select statement, after 30 seconds every REST request fails with 401 - unauthorized.
I set in Auth Repository the 'Access Token Expiration Time' of my OAuth 2.0 (Azure) profile to Custom/25 Seconds but nothing changed.
I could not find anything on static variables so I implemented the following:
//test case property "Duration" to simulate static variable
//get value of property "Duration"
def dur = testRunner.testCase.getPropertyValue("Duration").toInteger()
//if test is more than 'Duration' get another token and increment 'Duration'
if ( testRunner.getTimeTaken() > dur)
testRunner.testCase.setPropertyValue( "Duration", (dur+30000).toString() )
dur = testRunner.testCase.getPropertyValue("Duration").toInteger()
This solution has 2 issues:
- 1. For every test I need an extra Initialisation step to reset the Duration property to (testRunner.testCase.setPropertyValue( 'Duration', '30000' ) for the next run
- 2. After running the Get Access token step, ReadyAPI continues on with a new Data Source step so the test will never end!
The only way I see how to resolve this is instead of asking ReadyAPI to run step GetAcessToken:
is to replace this line of code with all the code of step GetAcessToken.
Surely there must be a more elegant solution
Solved! Go to Solution.
My "final Solution":
I implemented event TestRunListener.beforeRun which runs before each test. Here I get a new access token and initialize the Duration property to a few minutes less than the life of the token.
My tests have a Datasource step, the Rest request, the Assert step and finally the Data Source loop step.
In the Assert step, if testRunenr.getTimeTaken() > Duration (i.e. my test has been running for a time approaching the token expiration), I get a new token and increment the value of the Duration property by another chuck of minutes equal to a few minutes less than the life of the token.
I tried in vain to implement the acquiring of the new token as a script library method (getNewAccessToken(project)) so that I don't have to copy/paste the same code in every Assert test-step, but ReadyApi says I have a compilation error and I don't know how to debug ReadyAPI groovy library scripts. I have other script library methods that work fine... furthermore, the code in the method is almost identical to the code in the TestRunListener.beforeRun event except that I'm passing the project as a parameter... Still, it does not work and I have no way of debugging it!
You have 5 steps listed in your original question... Why not switch positions between 1 and 2? You get a new token each loop before the REST step is invoked. Is there a price to pay for generating a Token? If not, why not just regenerate the token inside the loop.
The acquisition of a new access token is very slow so I can't afford to have it inside the loop. As you can see from the code snippet below I request for a new token and then wait in a loop till I have one:
def oldToken = oAuthProfile.getAccessToken();
def oAuthClientFacade = new OltuOAuth2AzureClientFacade (TokenType.ACCESS);
while(oldToken == oAuthProfile.getAccessToken())
I'm pretty happy with what I've got now:
I get the access token in the TestRunListener.beforeRun event which also sets a test case property "Duration" to the time I want to wait till I need another token.
Inside the test loop, in my groovy asserts script, I check if the test has been running for a time exceeding the Duration property, and if yes, I get a new access token and increment the Duration property