Groovy : why this code doesn't work ? unable to resolve class - groovy

I have this test code:
def p = [:]
p.foo = [:]
p.foo.bar = 120
p.foo.bar - 3
(p.foo.bar) + 3
why on the last statement i get a compilation error : "unable to resolve class p.foo.bar "?
Thanks for the help
Groovy version 1.8.1

OK, I think I figured it out. I ran the AST browser against your sample script (using the GroovyConsole). It would only show an output at the Conversion phase. At this phase you can see how the script is converted. The key is that the last line is converted into this:
...
((1) as p.foo.bar)
This means that, apparently, it's trying to cast or convert the 1 into a class named p.foo.bar.
You can dig a little deeper and see that the parser is parsing the statement like this:
(p.foo.bar)(+1)
Which is the same as
(p.foo.bar)1
Therefore, the parser/compiler is seeing the + as a unary + operator. And that is why you are getting the error. (The way around it it to remove the parentheses, or swap the order of the arguments!)

Related

How to store windows system path in JMeter JSR223 sampler using groovy strings?

I am building a config in Jmeter where I specializing a system windows path to load CSV and write into CSV files. The path contains "" symbol.
There are some samplers with JSR223 PreProcessors and JSR223 Samplers. Language used is Groovy.
I know that I should screen symbols such this, but I am a bit lost at the moment because I do not understand why different options work sometimes and do not other times.
Initial path is "C:\user\jmeter\csv"
How I define this in jMeter JSR223:
def systemPath = "C:\\user\\jmeter\\csv\\"
Sometimes it works, but after I've changed some lines of code it won't!
Next time I've tried:
def systemPath = "C:\\\user\\\jmeter\\\csv\\\"
It worked for me for a while but after some code alterations after this line it won't work again.
I also 've read an article https://www.baeldung.com/groovy-strings and tried everything, but still I get this error every time:
javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script343.groovy: 2: Unexpected input: '"' # line 2, column 16.
def systemPath = "C:\user\jmeter\csv\";
I want to store this system path reliably without errors and understand why I get this error.
I don't see any problems with this line:
def systemPath = "C:\\user\\jmeter\\csv\\"
this one is not good:
def systemPath = "C:\\\user\\\jmeter\\\csv\\\"
Your "work sometimes and do not other times" statement doesn't add any value unless you show jmeter.log preferably with debug level of verbosity for "working" and "not working" cases.
For the time being consider the following hints:
You can use forward slashes instead of escaping, i.e.
def systemPath = "C:/user/jmeter/csv/"
Or you can use File.separator property to get OS-specific "slash" value like:
def systemPath = "C:" + File.separator + "user" + File.separator + "jmeter" + File.separator + "csv" + File.separator
If you think that " character is a problem (it needs to be escaped as well by the way) you can declare Groovy strings using ' characters like:
def systemPath = 'C:\\user\\jmeter\\csv\\'

How can I get a list of variable names from a lark-parser Tree?

I am using python 3.8.5 and lark-parser 0.11.2. I have a question about Visitors.
I have a grammar for my needs and Lark is working great. I have a case where,
under some conditions, I want to evaluate a returned parse tree and scan it to
get a, possibly empty, list of variable names appearing in the tree.
A sample expression is:
count + num_items
The parse tree from the expression is:
Tree('add', [Tree('variable', [Token('VARIABLE', 'count')]), Tree('variable', [Token('VARIABLE', 'num_items')])])
I figured that I would write a Visitor class that would scann the tree for variables and store them in an internal list:
from lark import Visitor, v_args
#v_args(inline=True)
class FindVariables(Visitor):
def __init__(self):
super().__init__()
self.variable_list = []
def variable(self, var):
try:
self.variable_list.append(var)
except Exception as e:
raise
I am trying to use it as:
fv = FindVariables()
fv2 = fv.visit(parse_result)
for var in fv.variable_list:
...
The issue I have is that when fv = FindVariables() is executed I get a
TypeError exception:
f() missing 1 required positional argument: 'self'
If I change the call above to:
fv = FindVariables().visit(parse_result)
the statement runs but fv does not "see" variable_list.
I am probably misusing the Visitor class. Is there a best/better way to approach this?
Well, I am answering my question but I am not sure that it is the answer.
I changed Visitor to Transformer in the code block in the question and it just worked.
I am glad that I have a solution but it feels like Visitor should have been the right tool here. Still happy to find out if I am misusing the lib here and if there is a better way.

Jmeter - groovy function not working as expected

I have a groovy function which performs some date operations. i.e. Returns a date 12 months forward. This date is encoded and stored into a variable.
snippet:
${__groovy(import groovy.time.TimeCategory; def now = new Date(); use(TimeCategory) { def nowPlusOneYear = now + 12.month - 1.day; return URLEncoder.encode(nowPlusOneYear.format('dd/MM/YYYY')\, 'UTF-8')},Policy_ExpiryDate)}
The above code works well with a JSR223 Sampler. Also, the variable name and its value gets displayed in debug sampler.
But, when I use this code along with a GET HTTP Request. The value doesn't gets substituted.
the request:
/IIMS/target/source/UNDERWRITING/ValidatorAction.action?dataString=%7B%22Testing%22%3A%22F%22%2C%22VCURRENTSTATUSNAME%22%3A%22%22%2C%22Entry%20Date%22%3A%22${__urlencode(${__time(dd/MM/YYYY,Entry_Date)})}%22%2C%22Policy%20Type%22%3A%22FLEET%22%2C%22Policy%20Inception%20Date%22%3A%22${__urlencode(${__time(dd/MM/YYYY,Policy_InceptionDate)})}%22%2C%22Policy%20Inception%20Time%22%3A%22${__urlencode(${__time(HH:mm:ss,Policy_InceptionTime)})}%22%2C%22Policy%20Duration%22%3A%2212%22%2C%22Unit%22%3A%22F%22%2C%22Policy%20Expiry%20Date%22%3A%22${__groovy(import groovy.time.TimeCategory; def now = new Date(); use(TimeCategory) { def nowPlusOneYear = now + 12.month - 1.day; return URLEncoder.encode(nowPlusOneYear.format('dd/MM/YYYY')\, 'UTF-8')},Policy_ExpiryDate)}%22%2C%22Policy%20Expiry%20Time%22%3A%2223%3A59%3A59%22%2C%22Type%20Of%20Business%22%3A%22CASH%22%2C%22Payment%20Frequency%22%3A%22B%22%2C%22Country%22%3A%22UAE%22%2C%22Source%20of%20Business%22%3A%220DIR%22%2C%22Policy%20branch%22%3A%22${UserDetails_g5}%22%2C%22UMR%20Number%22%3A%22%22%2C%22Equator%20Policy%22%3A%22N%22%2C%22Policy%20holder%22%3A%22${PolicyHolderDetails_g1}%22%2C%22Policy%20holderNew%22%3A%22${PolicyHolderDetails_g2}%22%2C%22SEC-POLPLANNumber%20of%20Vehicles%20in%20Fleet%22%3A%220%22%2C%22SEC-POLPLANPolicy%20Plan%22%3A%22NA%22%2C%22SEC-POLPLANDistribution%20Channel%22%3A%22DIROIC%22%2C%22SEC-POLPLANName%20of%20the%20Scheme%22%3A%22NA%22%2C%22SEC-PLRIDPolicy%20Level%20FAC%20R%2FI%22%3A%22N%22%2C%22SEC-PLRIDPolicy%20Level%20FAC%20R%2FI%20percentage%22%3A%220%22%2C%22SEC-PLRIDPolicy%20Level%20Proportional%20FAC%20R%2FI%20percentage%22%3A%220%22%2C%22SEC-PLRIDPolicy%20Level%20Non%20Proportional%20FAC%20R%2FI%20percentage%22%3A%220%22%2C%22SEC-PLRIDProp%20Non%20Prop%20FAC%20Date%22%3A%22Y%22%2C%22SEC-CEDANTNumber%20of%20Cedants%20Involved%22%3A%22%22%2C%22SEC-CEDANTCedant%20Country%22%3A%22%22%2C%22SEC-MDPMinimum%20Deposit%20Premium%20Applicable%22%3A%22N%22%2C%22SEC-MDPMinimum%20Deposit%20Premium%20Type%22%3A%22%22%2C%22SEC-MDPPercentage%20of%20Premium%22%3A%22%22%2C%22SEC-MDPMinimum%20Deposit%20Premium%22%3A%22%22%2C%22SEC-MDPMinimum%20premium%22%3A%22%22%2C%22SEC-CRMCRM%20Reference%20Number%22%3A%22${__Random(1111111,9999999,CRM_RefNo)}%22%2C%22pBusinessTranCode%22%3A%22SCR-BSCDTL%22%2C%22pSaveContinueIndicator%22%3A%22%22%2C%22pJSPName%22%3A%22BasicInformation.jsp%22%2C%22crtPartyFunctionInd%22%3A%22Y%22%2C%22strTOC%22%3A%22%22%2C%22existingPartyIndicator%22%3A%22Y%22%2C%22disabledSectionCode%22%3A%22%22%2C%22scriptaculous%22%3A%22%22%2C%22language%22%3A%22null%22%2C%22policyId%22%3A%22null%22%2C%22policyPlanUpgradation%22%3A%22N%22%2C%22reason%22%3A%22%22%2C%22isMasterQuote%22%3A%22FALSE%22%2C%22USERCODE%22%3A%22${UserDetails_g6}%22%2C%22pVersionDate%22%3A%22%22%2C%22__endorsementType%22%3A%22null%22%2C%22cSystemDate%22%3A%22${__urlencode(${__time(dd/MM/YYYY,cSystemDate)})}%22%2C%22cedantEndrDate%22%3A%2208%2F12%2F2117%22%2C%22CIMS_CSRFTOKEN%22%3A%22${CIMS_CSRFTOKEN}%22%7D%3B&productCode=0101&productId=1030885614052014
All values get substituted properly except for the groovy part. Am I missing something over here. The debug sampler doesn't shows a variable named Policy_ExpiryDate.
I cannot reproduce your issue, __groovy() function is normally getting evaluated and the substituted by its respective value:
If it doesn't for you - most probably it fails somewhere somehow, check jmeter.log file for any suspicious entries
Also you can execute the function anywhere else, for example in User Defined Variables configuration element and refer the value where required just as ${Policy_ExpiryDate}
__groovy() works well with Jmeter 5.4. But this function is not recognized in Jmeter 5.3.
Thanks a lot for your help #Dmitri T
Regards,
Ajith

How to replace the call to random.randint() in a function tested with pytest?

I'm new to programming and did search a lot through the questions but couldn't find an answer to my present problem.
I am writing a little game in python 3.8 and use pytest to run some basic tests.
One of my tests is about a function using random.randint()
Here's an extract of my code :
import random
...
def hit(self, enemy, attack):
dmg = random.randint(self.weapon.damage_min, self.weapon.damage_max) + self.strength // 4
hit() does other things after that but the problem is with this first line.
I tried to use monkeypatching to get a fake random number for the test :
def test_player_hit_missed(monkeypatch, monster, hero):
monkeypatch.setattr('random.randint', -3)
hero.hit(monster, 'Scream')
assert monster.life == 55
When I run the test, I get this error :
TypeError: 'int' object is not callable
From what I understand, the monkey-patch did replace randint() by the number I indicated (-3), but then my function hit() did try to call it nonetheless.
I thought -3 would replace randint()'s result.
Can someone explain me :
- why this doesn't work (I probably haven't correctly understood the behavior of the monkeypatch) ?
- and how I can replace the call to random.randint() by the value -3 during the test ?
Thanks

Second map value is always null, even if it prints out 1

I have some code getting data and then selecting it in order. For this I use simple maps that I may later access with ease (I thought..).
I use the following code within a loop to insert maps to another map named "companies":
def x = [:]
x.put(it.category[i], it.amount[i])
companies.put(it.company, x)
And I can surely write the result out: [Microsoft:[Food:1], Apple:[Food:1]]
But then, when I am about to get the food value of each company it always is null. This is the code I use to get the values:
def val = companies.get(it.company).get(key.toString())
def val = companies[it.company][key] // doesn't make a difference
Val is always null. Can someone help and / or explain why I have this error. What am I doing wrong? I mean, I can clearly see the 1 when I print it out..
My guess is that it.category[i] and key are completely different types...
One thing you could try is:
x.put(it.category[i].toString(), it.amount[i])
and then
def val = companies[it.company][key.toString()] // doesn't make a difference
The solution was simple to make the category as a string:
x.put(it.category[i].toString(), it.amount[i])
And after that little fix it all works as expected.

Resources