Unanswered question

API Testing with Neoload?

looking to use Neoload for API testing.
Web request is simple but has a large amount of JSON included in each header.
JSON contains beginning and end parts but also a variable number of lines in the middle.
The JSON payload needs to be different and also need to have varying number of lines. As it's an api there need to be a large number of requests that can be used once only.
Tried several ways to load this. First tried to create a file variable with each entry as a a separate JSON payload (built using a PERL script.) Works ok in small volumes but will not support the final load as the file becomes too large - it'll be several GB!.
Next tried to create a file variable that has a list of multiple files each containing a JSON payload, Then use javascript to load the contents into a string variable.
Javascript is:
var dataFile = context.variableManager.getValue("dataFile.payloadFile");
var dataPath = context.variableManager.getValue("dataPath");

//logger.debug("dataFile=" + dataFile);
//logger.debug("dataPath=" + dataPath);
var payloadFile = dataPath + "/" + dataFile;
logger.debug("payloadFile=" + payloadFile);

// reads file contents

var file = new java.io.File(payloadFile);
var inppt = new java.io.StreamReader(new java.io.FileReader(file));
var dataPayload = inppt.readLine();
inppt.close();
logger.debug("dataPayload=" + dataPayload);

// Inject the computed value in a runtime variable
context.variableManager.setValue("dataPayload",dataPayload);
This works for 1 or 2 iterations then crashes.
Also tried to build dynamically using a javascript to build 'on the fly'. (Done similar before in other tests.). Javascript is:
var vendorName = context.variableManager.getValue("vendor.vendorName");
if (vendorName == null) {
context.fail("Variable 'vendor.vendorName' not found");
}
var vendorGST = context.variableManager.getValue("vendor.vendorGST");
if (vendorName == null) {
context.fail("Variable 'vendor.vendorName' not found");
}
var vendorID = context.variableManager.getValue("vendor.vendorID");
if (vendorID == null) {
context.fail("Variable 'vendor.vendorID' not found");
}
var lineSeq = context.variableManager.getValue("lineSeq");
if (lineSeq == null) {
context.fail("Variable 'lineSeq' not found");
}
var declarationDate = context.variableManager.getValue("DeclarationDate");
if (declarationDate == null) {
context.fail("Variable 'DeclarationDate'' not found");
}

var jsonPayload = '{ "pmsSoftwareName": "Planit Test Harness", "pmsSoftwareVersion": " 0.0.3",';
jsonPayload = jsonPayload + '"vendor": {"vendorName": "' + vendorName + '","vendorGST": "' + vendorGST + '","vendorID": "' + vendorID + '","vendorPhone": null },';
jsonPayload = jsonPayload + '"comment": "Invoice ' + lineSeq + '", "lines": [';

//Get Total Number of Extracted Values
var lineTotal = context.variableManager.getValue("lineTotal");
if (lineTotal == null) {
context.fail("Variable 'lineTotal' not found");
}
lineTotal = parseInt(lineTotal);
lineTotal = 10;

function pad(num, size) {
var s = num+"";
while (s.length < size) s = "0" + s;
return s;
}

//Loop through each value and add them to the string
for(var i = 1; i <= lineTotal; i++) {
//get all the values for this item
var claimId = "VF00455";
var accidentDate = "2017-10-" + pad(parseInt((27*Math.random())+ 1),2);
var serviceCodes = "ACU1";
var serviceDate = "2018-10-" + pad(parseInt((27*Math.random())+ 1),2);
var purchaseOrderNumber = "";
var hoursClaimed = 1;
var minutesClaimed = 1;
var invoiceComment = "Invoice: " + lineSeq + "; Line: " + i;
var invoiceAmount = 0.01;
var NHINumber = "BAB2456";
var dateOfBirth = "1990-10-" + pad(parseInt((27*Math.random())+ 1),2);
var claimantFirstName = "Bill";
var claimantFamilyName = "Bloggs";
var providerID = "J99966";
var providerFirstName = "ProviderFirstName";
var providerSurname = "ProviderSurname";

//Build line item string
var lineString = ' { "claimId": "' + claimId + '","accidentDate": "' + accidentDate + '","lineDetails": { "serviceCodes": ["' + serviceCodes + '"],';
lineString = lineString + '"serviceDate": "' + serviceDate + '","purchaseOrderNumber": null, "billing": {"billingMethod": "time", "hoursClaimed": ' + hoursClaimed;
lineString = lineString + ', "minutesClaimed": '+ minutesClaimed + ' }, "invoiceComment": "' + invoiceComment + '", "invoiceAmount": ' + invoiceAmount + ' },';
lineString = lineString + '"patient": { "nhi": "' + NHINumber + '", "dateOfBirth": "' + dateOfBirth + '", "firstName": "' + claimantFirstName
lineString = lineString + '", "middleName": null, "surname": "' + claimantFamilyName + '" },' + '"provider": { "providerId": "' + providerID + '", "firstName": "';
lineString = lineString + providerFirstName + '", "middleName": null,"surname": "' + providerSurname + '", "facilityId": null } } ';

//add comma except on last line item
if(lineTotal != i) {
lineString = lineString + ",";
}
// logger.debug("lineString= " + lineString);
jsonPayload = jsonPayload + lineString;
}
var contractId = "79/45";
var jsonPayloadEnd = ' ], "contractId": "' + contractId + '", "declaration": { "declarationDate": "' + declarationDate + '" } }';

jsonPayload = jsonPayload + jsonPayloadEnd ;
//logger.debug("jsonPayload="+ jsonPayload);

// Inject the computed value in a runtime variable
context.variableManager.setValue("jsonPayload",jsonPayload);

This too works for a couple of iterations and fails.

Using Neoload 6.6 - also tried 6.0 in case it was a version problem.

Suggestions?

Clive W.
Clive W.

Clive W.

Level
0
57 / 100
points

Answers

I understand that your requests and headers content can be huge but what type of errors did you get when you said that it started to fail? Is it out of memory issue or else?

Also you mentionned several GB of data. Do you mean that your request body will contain such amount of data to be sent?

It seems unusual to send such amount of data against an API service.

Clive W.
Clive W.

Clive W.

Level
0
57 / 100
points

For my 1st approach, I would need a file of several GB to contain all the api JSON. That file needs to be loaded as a parameter file in NeoLoad, The average load is over 4000 api calls per hour so need to drive beyond this. If I generate say 10,000 entries, I get a file of 1.3GB. If I try to load this into Neoload, not surprisingly Neoload hangs and goes non-responsive for a while. It appears to load and I can execute but I'm concerned such a large file may comprise the integrity of the test.
When using the 'generate on fly' script I get the following stack trace dump.
2018/11/13 10:01:18 FATAL - neoload.Misc: Error while calling evaluateScript method java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.neotys.nl.js.f.a(f.java:50)
at com.neotys.nl.lg.engine.Q.internalExecute(Q.java:61)
at com.neotys.nl.lg.engine.l.a(l.java:146)
at com.neotys.nl.lg.engine.v.c(v.java:125)
at com.neotys.nl.lg.engine.w.internalExecute(w.java:83)
at com.neotys.nl.lg.engine.l.a(l.java:146)
at com.neotys.nl.lg.engine.H.i(H.java:251)
at com.neotys.nl.lg.engine.H.internalExecute(H.java:98)
at com.neotys.nl.lg.engine.l.a(l.java:146)
at com.neotys.nl.lg.engine.c.a(c.java:177)
at com.neotys.nl.lg.engine.c.run(c.java:108)
Caused by: java.lang.IllegalAccessError: class sun.reflect.GeneratedMethodAccessor8 cannot access its superclass sun.reflect.MethodAccessorImpl
at sun.misc.Unsafe.defineClass(Native Method)
at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:63)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:399)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:394)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:393)
at sun.reflect.MethodAccessorGenerator.generateMethod(MethodAccessorGenerator.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:53)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.neotys.nl.js.c.a(c.java:38)
at com.neotys.nl.js.c.g(c.java:102)
at com.neotys.nl.js.api.i.e(i.java:90)
at com.neotys.nl.js.api.VariableManager.interpretVariableName(VariableManager.java:169)
at com.neotys.nl.js.api.VariableManager.jsFunction_getValue(VariableManager.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:161)
at org.mozilla.javascript.FunctionObject.call(FunctionObject.java:476)
at org.mozilla.javascript.optimizer.OptRuntime.call1(OptRuntime.java:66)
at org.mozilla.javascript.gen.generatePayload_3._c_script_0(generatePayload:7)
at org.mozilla.javascript.gen.generatePayload_3.call(generatePayload)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:426)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3178)
at org.mozilla.javascript.gen.generatePayload_3.call(generatePayload)
at org.mozilla.javascript.gen.generatePayload_3.exec(generatePayload)
at com.neotys.nl.js.api.d.evaluateScript(d.java:351)
... 15 more