How To Use Session Affinity in Data Center Tests or Automation
Description
Atlassian Jira and Confluence have Data Center (Cluster) editions. Many Data Center installations use a load balancer that uses session affinity to distribute work to nodes in the cluster. This can present a challenge when writing testcases or automation that may be impacted by inter-node latency. For example, an issue created on one node may not immediately show up in a JQL search run on another node. The latency is usually very low (seconds) but any automation can be impacted in these cases. While a simplistic approach is to put in sleep delays in the hopes of mitigating this problem, there are better ways.
Some documentation refers to session affinity as sticky sessions. See Atlassian documentation like Load Balancer Configuration Options for more information.
Use Session Affinity
Both the JCLI and CSOAP support session authentication. Any actions run as part of a run or runFrom action automatically take advantage of session authentication and therefore support session affinity based clusters - namely running all the actions in the script on the same node.
However, GINT based test or automation scripts normally use a separate CLI action per testcase and therefore there is no automatic session affinity unless some additional work is done.
The best approach is if your Data Center is configured to use IP hash or equivalent as discussed in Load balancer configuration options. This keeps automation script requests going to the same node automatically.
IP hash
The load balancer calculates a hash value based on the client's IP address, and then uses that hash value to assign a node to the new session. This algorithm ensures that requests from the same IP address go to the same node as long as it is available.
If the above approach is not implemented in your Data Center, then you will have more work to do. Here is what to add to the script to enable this. Basically, all you need to do is login and use the session token provide in subsequent actions.
These examples require Release 2.8 or higher.
Example - Jira
... includeTool << GintForJira ... def info = gint.getServerInfoWithVerify() // verify server is available, otherwise end test ... gint.add( action: 'login', description: 'Get a login token for session affinity and change the default jira command generator to use it', neededBy: true, // make sure this testcase runs before any other testcase finalClosure: { testcase -> def parameters = gint.getCmdGeneratorParameters() + [cli: helper.getParameterValueWithExtendedLookup('cli') + ' --login ' + testcase.outData[0]] gint.setCmdGenerator(gint.getGintCmdGenerator().getGenerator('confluenceMacro', parameters)) }, ) // Clean-up the session at the end target(name: 'final', description: 'Run this last', prehook: [], posthook: []) { helper.runCmd(cmd: gint.getCmd(action: 'logout')) // getCmd uses the jira command generator }
Example - Confluence
... includeTool << GintForConfluence ... def info = gint.getServerInfoWithVerify() // verify server is available, otherwise end test ... gint.add( action: 'login', description: 'Get a login token for session affinity and change the default confluence command generator to use it', neededBy: true, // make sure this testcase runs before any other testcase finalClosure: { testcase -> def parameters = gint.getCmdGeneratorParameters() + [cli: helper.getParameterValueWithExtendedLookup('cli') + ' --login ' + testcase.outData[0]] gint.setCmdGenerator(gint.getGintCmdGenerator().getGenerator('confluenceMacro', parameters)) }, ) // Clean-up the session at the end target(name: 'final', description: 'Run this last', prehook: [], posthook: []) { helper.runCmd(cmd: gint.getCmd(action: 'logout')) // getCmd uses the confluence command generator }
Related content
© 2005 -2024 gint.org