JMeter - How to read JSON file? - jmeter

I used the CSV format for the data files in JMeter. Our VP wants to change the format to JSON. How can I read a JSON file from the disk?

You have at least 2 options:
Use HTTP Request sampler and file protocol like:
JSON files are basically plain-text files so you will be able to use JSON Extractor or JSON Path Extractor to parse JSON data and store the result into JMeter Variables for later reuse
References:
Jayway JsonPath - Getting Started
Advanced Usage of the JSON Path Extractor in JMeter
Use JSR223 Test Elements and Groovy language. Groovy has built-in JSON support via JsonSlurper so you will be able to parse the JSON file programmatically.
References:
The Groovy programming language - Parsing and producing JSON
Groovy - JSON

The best solution for this problem is to use JSR223 Sampler to read JSON file and load into the vars or props and use it wherever it is required.
For this,
Add a JSR223 Sampler in JMeter
Add the below code
import java.io.File
import java.util.Base64
def propertiesFromMap(map, prefix) {
for (item in map) {
id = prefix+item.key;
if (item.value instanceof Map) {
propertiesFromMap(item.value, id+".");
} else {
value = item.value.toString();
log.info("Loading property " + id + ": " + value);
if(value.startsWith("ENC:")) {
props.put(id, new String(Base64.getDecoder().decode(value.substring(4, value.length()))));
} else {
props.put(id, value);
}
}
}
}
def baseDir = org.apache.jmeter.services.FileServer.getFileServer().getBaseDir();
def jsonFilePath= baseDir + "/configs/" + "configuration-dev" + ".json";
log.info("Loading properties from " + jsonFilePath);
def jsonMap = new groovy.json.JsonSlurper().parse(new java.io.File(jsonFilePath));
propertiesFromMap(jsonMap, '');
Create a directory named configs where you placed the .jmx file
Create a file named configuration-dev.json in configs directory
Add JSON content e.g. in the file:
{
"key1": "value1",
"key2": "value2",
"key3": "ENC:base64_encoded_value"
"group1": {
"grp1_key": "value"
}
Access values in Samplers e.g. ${__P(key1)}, it will return value of key1. For group1 variables access e.g. ${__P(group1.grp1_key)}
For accessing the values into JSR223 use props e.g. props.get("key1")
You can pass base64 encoded values into JSON by adding ENC: as value prefix which will be resolved automatically when accessing values from props or __P()

Related

Validate the response from JDBC request using beanshell or JSR223

For my JDBC request, the following result I am receiving from Oracle DB and want to validate the response should not give more than 1 records and EVENT_LOG_ID=48144960
AUDIT_CONTEXT_KEY, EVENT_LOG_VALUE, EVENT_LOG_ID, EVENT_LOGGED_DTTM
72454_2021-09-16T07:44:41.439Z ENG_SITE 48144960 16-SEP-21 07.44.43.456000000 AM
Config Details:
Result Details:
Debugger Sampler Result:
dataFromDB=[{EVENT_LOG_VALUE=ENG_SITE, EVENT_LOG_ID=48144960, EVENT_LOGGED_DTTM=2021-09-16 07:44:43.456, AUDIT_CONTEXT_KEY=72454_2021-09-16T07:44:41.439Z}]
Please add a JSR223 Assertion with the following code, this will validate what you are looking for,
1.upto(vars.get('AUDIT_CONTEXT_KEY_#') as int, {
if (vars.get('AUDIT_CONTEXT_KEY_' + it) == '1') {
if (vars.get('EVENT_LOG_ID_' + it) != '48144960') {
AssertionResult.setFailure(true)
}
}
})

While controller is not working correctly

On a http request, getting a task status as ongoing but want to run it in loop till it is sucessful. I am using while controller with a counter which is not working.
http response
{
"data": {
"uri": null,
"taskId": "f5b6aaf3-8b14-49ba-a495-788eef5c523b",
"taskStatus": "Ongoing"
},
"apiUrl": "http:\/\/imp-901v.pii.int:8081\/release01-nightly-api\/\/2192_IND_1_40",
"statusCode": "102"
}
setting for while controller :
setting for counter:
transaction setting
user defined variable:
What I missed here ?
There are at least following problems with your script:
You need to put statsCounter as the "Exported Variable Name" in the Counter (or just remove the counter and use __jm__While Controller__idx pre-defined variable instead)
You need to change props to vars
props - is a shorthand for JMeter Properties
vars - is a shorthand for JMeter Variables
More information: Top 8 JMeter Java Classes You Should Be Using with Groovy

How to assert failure if string is in JSON response from http request JMeter

I am trying to write a test that ensures that the name property in a JSON response is not MYGROUP. I'm stuck here because I'm trying to use the code from a test that checks that the name property is MYGROUP. I know I need to fix something in the if condition of this test:
# Check AD group deletion
- url: ${ADSubscriptions}/${NetworkID}/clientsyncs/${syncId}/groups
label: 1360_CheckADGroupDeletion
method: GET
headers:
Authorization: Bearer ${access_token}
Content-Type: "application/json"
Accept: "application/json, text/plain, */*"
assert-httpcode:
- 200
- 202
jsr223:
- langauge: groovy
execute: after
script-text: |
import groovy.json.JsonSlurper
def slurperresponse = new JsonSlurper().parseText(prev.getResponseDataAsString())
for (entry in slurperresponse){
if(entry.name == "MYGROUP" || entry.name == "mygroup" ){
{RETURN FALSE HERE}
break;
}
}
- langauge: groovy
execute: after
script-file: jsr223/logger.groovy
parameters: check_adgroup_deletion
The expected json structure for the request used in the test looks like this:
[
{
"id": "id1",
"name": "MYGROUP",
"selected": true
}
]
The above response would equate to a failing test. The below would equate to a passing test.
[
{
"id": "id1",
"name": "MYGROUP",
"selected": false
}
]
The code snippet you're looking for is prev.setSuccessful(false) where prev stands for the parent SampleResult class instance.
See the above JavaDoc for all available functions and Top 8 JMeter Java Classes You Should Be Using with Groovy article to learn more about JMeter API shorthands available for JSR223 blocks.
In particular your case it would be easier to use assert-jsonpath Taurus assertion

Text formatting in Yaml "example:"

I'm trying to display some formatted text in a YAML file (in the example: key):
log_level_per_component:
type: object
example:
"{
\"Component1\": \"Info\",\n
\"Component2\": \"Debug\",\n
\"Component3\": \"Fatal\",\n
...\n
}"
for getting such a Swagger output:
"log_level_per_component": "{
"Component1": "Info",n
"Component2": "Debug",n
"Component3": "Fatal",n
...
}"
but I always get this:
"log_level_per_component": "{ \"Component1\": \"Info\",\n \"Component2\":
\"Debug\",\n \"Component3\": \"Fatal\",\n ...\n }"
Any idea what I can do to fix it?
Update 2018-05-17 for Helen's screenshot request about her solution:
This is what I get with both solutions by using "example:":
And this what I get by using "examples:":
Both are always empty.
YAML is a superset of JSON, so you can use the normal JSON object literal syntax in YAML:
log_level_per_component:
type: object
example:
{
"Component1": "Info",
"Component2": "Debug",
"Component3": "Fatal"
}
Alternatively, you can use YAML object syntax, and Swagger UI will render the example as JSON (provided that your request or response type is JSON):
log_level_per_component:
type: object
example:
Component1: Info
Component2: Debug
Component3: Fatal

Custom protoc plugin parsing not working for custom options

I am trying to write a protoc plugin that requires me to use custom options. I defined my custom option as shown in the example (https://developers.google.com/protocol-buffers/docs/proto#customoptions):
import "google/protobuf/descriptor.proto";
extend google.protobuf.MessageOptions {
string my_option = 51234;
}
I use it as follows:
message Hello {
bool greeting = 1;
string name = 2;
int32 number = 3;
option (my_option) = "telephone";
}
However, when I read the parsed request, the options field is empty for the "Hello" message.
I am doing the following to read
data = sys.stdin.read()
request = plugin.CodeGeneratorRequest()
request.ParseFromString(data)
When I print "request," it just gives me this
message_type {
name: "Hello"
field {
name: "greeting"
number: 1
label: LABEL_REQUIRED
type: TYPE_BOOL
json_name: "greeting"
}
field {
name: "name"
number: 2
label: LABEL_REQUIRED
type: TYPE_STRING
json_name: "name"
}
field {
name: "number"
number: 3
label: LABEL_OPTIONAL
type: TYPE_INT32
json_name: "number"
}
options {
}
}
As seen, the options field is empty even though I defined options in my .proto file. Is my syntax incorrect for defining custom options? Or could it be a problem with my version of protoc?
I'm making my protobuf python plugin.
I also got the problem like yours and i have found a solution for that.
Put your custom options to a file my_custom.proto
Use protoc to gen a python file from my_custom.proto => my_custom_pb2.py
In your python plugin code, import my_custom_pb2.py import my_custom_pb2
Turns out you need to have the _pb2.py file imported for the .proto file in which the custom option is defined. For example, it you are parsing a file (using ParseFromString) called example.proto which uses a custom option defined in option.proto, you must import option_pb2.py in the Python file that calls ParseFromString.

Resources