Background:
I have an API that returns a response like so:
{
"status": 1,
"errorCode": null,
"message": null,
"data": [
{
"id": 33,
"snapshotId": 2,
"ceId": 29,
"month": "Feb",
"corpRcvPayAmt": 100000,
"wthRcvPayAmt": -90000
},
{
"id": 31,
"snapshotId": 2,
"ceId": 29,
"month": "Jan",
"corpRcvPayAmt": 0,
"wthRcvPayAmt": 0
}
]
}
The data node can vary from 0 size to 12 (empty to 1 per month). The only constant field for data is the "month" node. Other field values are changing.
Goal:
I want to do either a PUT or a POST request, depending on whether or not a specific month is already present in data.
For this, I'm capturing the entire data field into a variable using a Regular Expression Extractor like this:
With the sample response above, calling ${data} will give me {"id":33,"snapshotId":2,"ceId":29,"month":"Feb","corpRcvPayAmt":100000.00,"wthRcvPayAmt":-90000.00},{"id":31,"snapshotId":2,"ceId":29,"month":"Jan","corpRcvPayAmt":0.00,"wthRcvPayAmt":0.00}
Now using this field, I just want to do a simple if condition like so: if ${data} contains ${month} do something (PUT request). I'm currently trying to do it like this:
Problem:
The condition ${__groovy("${data}".contains("Jan"))} does not seem to work.
I've already tried doing the following:
change the condition to ${__groovy("${month}".contains("Jan"))} just to see if the syntax is correct. This works just fine.
Add a debug sampler inside the if controller using the condition ${__groovy("${month}".contains("Jan"))} to print ${data}. This also prints the data as expected.
I also tried using various js syntax for the if condition but so far groovy is the ongiving the best results.
With this I can confirm the following:
${month} and ${data} are extracted and stored properly
groovy syntax for string contains is working properly
for some reason, the condition ${__groovy("${data}".contains("Jan"))} is not working.
What am I missing here? Thanks in advance.
Don't reference JMeter Functions and/or Variables in Groovy scripts as:
There could be a conflict with GString Template
For JSR223 Test Elements it causes compilation cache feature malfunction reducing the performance
Your variable might simply resolve into something which will cause Groovy script compilation failure and/or malfunction. You can check jmeter.log file for the actual error details.
So instead of using ${data} go for vars.get("data") instead, vars is a shorthand for JMeterVariables class instance and this is the best way of getting a JMeter Variable value from the Groovy script.
The whole function should look like:
${__groovy(vars.get('data').contains("Jan"),)}
Also be aware that it's better to use JSON Extractor for obtaining values from JSON responses.
Related
not too sure if this is a user error but I can't seem to get this working. I have a test that returns 200 and this always hits the If controller, but the following fails.
I get a productID, if this is nested then i get the first one.
Regex is
prodID
"ProductId":(.*?),
$1$
0
Then as I want to use this in another thread group I cjhange to a property:
${__setProperty(prodID-${__threadNum},${prodID},)}
Then i use If Controller as
${__P(prodID-${__threadNum})} == "18"
Then it runs the same regex, but this time with $2$
Problem is that the If Controller isn't getting run on any, is there a way I can see this, or even is the above correct?
Thanks
The If Controller run its children if the expression evaluates to true
You're giving 18 == "18", it is not equal to true therefore the children are not getting executed.
I would suggest using __groovy() function instead like:
${__groovy(props.get('prodID-' + ctx.getThreadNum()).equals('18'),)}
where
props is a shorthand for Properties class instance holding JMeter Properties
ctx is a shorthand for JMeterContext class instance
See Top 8 JMeter Java Classes You Should Be Using with Groovy article for more information on this and other JMeter API shorthands
I am trying to write a test case where an id exists in the list of id's
I tried following but it doesnt work.
expect(response['products'][0]['ids'][0]['product_id'])
.to include(product_1.id, product_2.id, product_3.id)
It fails everytime with error the expected id doesnt exist.
e.g expected '123' to include '343' and '543'
but when i step through the code all id's are there so dont get why its looking in only in two ids.
response['products'][0]['ids'][0]['product_id'] is a String: "123".
String#include? will return true here, for the following inputs: "", "1", "2", "3", "12", "23", and "123" -- but that's clearly not what you're trying to test!
You wanted to check that this product_id is in that list; not that it includes the list.
This is a slightly unusual test to run, since your expectation is somewhat fuzzy.
If this is a rails application (i.e. you're using ActiveSupport), then you can make use of Object#in? to write the test as follows:
expect(response['products'][0]['ids'][0]['product_id'])
.to be_in(product_1.id, product_2.id, product_3.id)
Or if we're just using vanilla ruby then perhaps use rspec's satisfy matcher:
expect(response['products'][0]['ids'][0]['product_id'])
.to satisfy { |product_id| [product_1.id, product_2.id, product_3.id].include?(product_id) }
You may also be tempted to simply reverse the order of the arguments -- which technically works, but is a little confusing since the code seems like you're running assertions on the wrong object:
expect([product_1.id, product_2.id, product_3.id])
.to include(response['products'][0]['ids'][0]['product_id'])
But back to the point of this being an "unusual test".
Presumably, you've written it this way because you're not certain which order the ids will be listed in - i.e. which product will actually be response['products'][0].
The test would be even better if you either:
Made the order known (but I cannot really advise how without seeing more detail), so that you don't need a fuzzy matcher in the first place, or
Only have 1 product returned by the response in this test, or
Change the test to read all three product_ids from the response, and then use the match_array matcher.
I'm implementing an asp.net core API with admin-on-rest.
A custom REST client communicates to the API endpoints, but the mapping is fairly standard.
When I try to implement a into the interface, the deletion of elements works fine. Still, I get an error on every edit or deletion view for an element with the following text: "Incorrect Element". The console is empty, and everything works as expected.
What causes the error - and how can I solve this?
I've attached a screenshot of the error popup.
Screenshot of the error
Update 1:
Here is the code of my custom REST client: customrestclient gist and the included fetch.js: fetch.js
Double check your custom restClient returns at least the id of the deleted resource inside a data object.
I was finally able to fix the issue. One of my API endpoints returned a list instead of a single element for one of my ReferenceInput-elements.
This was the content response before my change:
[{
"languageId": 2,
"id": 2,
"name": "Danish",
"isoCode": "dan"
}]
And this is the correct response, that does not trigger the error:
{
"languageId": 2,
"id": 2,
"name": "Danish",
"isoCode": "dan"
}
I am using this git
I am getting error data/config.json does not exist or could not be read.
How do I create json file or load one?
The configuration json file is missing from the source code, however, checking out how the json is parsed in ConfigManager should allow you to create one from scratch.
Just looking at what the property names and types are in that class you can work out something like this:
{
"clips":[
{
"silhouette":"add your silhouette filename here",
"background":"add your background filename here",
"duration":0
}
],
"useKinect":true,
"useGpu":false,
"name":"Your Application Name here",
"resizeSilhouette":false,
"mirrorSilhouette":false,
"resizeSilouhette":false,
"overlayVideo":true,
"useActionClips":false,
"silhouettePadding":{
"top":5,
"right":5,
"bottom":5,
"left":5
},
"centerOfMass":true,
"showTime":true,
"smoothSilhouette":0,
"crossfade":0,
"silhouetteCache":{
"enabled":false,
"minFrames":3,
"maxFrames":10
},
"scale":{
"width":640,
"height":480
},
"osc":{
"enabled":false,
"serverPort":12000,
"clientAddress":"127.0.0.1",
"clientPort":12001,
"channels":0
},
"actions":{
"frequency":1,
"clips":[
"clipName1","clipName2"
]
}
}
If you save this as config.json in your sketch's data folder it should load.
However, bare in mind this may also crash as I've just placed some dummy placeholder data to give you an idea. Fill in the data you think you know what it should be for your project and figure out the rest as you go along.
Unfortunately the github project you decided to use isn't documented, so this means you will have to go through all the source code and understand it before you get to use it.
I'm using the go-worker to process resque jobs. A job has a payload which has a nested JSON structure like this:
[{
"key-a":"val-a",
"key-b":"val-b",
"files":[{
"key-a": [
{"a":"b","c": "d"},
{"e":"f","g": "h"}
],
"key-b": [
{"a":"b","c": "d"},
{"e":"f","g": "h"}
]
}]
}]
Now go-worker gives me args ...interface{} which represents that JSON payload, not the actual JSON text. Is there an idiomatic way to convert that(args) to the correct types (could use another package to do this.) Using type assertions manually seems a bit tedious for such a thing.
If it's really giving you the actual go objects (i.e. a bunch of map[string]interface{} and not the json string itself) then there probably isn't much you can do besides a bunch of type assertions.
You could re-marshall it to json then parse it again into the correct structs, but that's a bit of a hack (and I have no idea if it would be performant or not).