How to send a rule for another agent in Jason? - agent

Jason comes with a demo that use the performative "tellRule" to send rules, but in my tests it is not working. I tried to send to the self agent like this:
.send(self,tellRule, [{a :- b & c}])
The result was:
Command .send(self,tellRule, [{a :- b & c}]): included for execution
Communication error -- no_applicable: Found a goal for which there is no applicable plan:+!kqml_received(self,tellRule,[{ a :- (b & c)}],mid511)

Actually, Jason has not "tellRule" performative defined by default. In fact, the mentioned demo is teaching how to add a KQML performative. So, to your code work, you should first create "tellRule", doing like this:
.send(self, tellHow, {+!kqml_received(A,tellRule,Rules,_) <-
.print("Received rule(s) ",Rules, " from ",A);
for ( .member(R, Rules) )
{+R[source(A)];}
.relevant_rules(_,LR);
.print("Rules: ",LR)}).
After this, you can run the command:
.send(self,tellRule, [{a :- b & c}]).
By the way, the same idea can be used to create something like "untellRule":
.send(self, tellHow, {+!kqml_received(A,untellRule,Rules,_) <-
.print("Removing rule(s) ",Rules, " from ",A);
for ( .member(R, Rules) )
{-R}}).
.send(self,untellRule,[{a :- b & c}]).

Related

How to make the translations work with the Python 3 "format" built-in method in Odoo?

Since Python v3, format is the primary API method to make variable substitutions and value formatting. However, Odoo is still using the Python 2 approach with the %s wildcard.
message = _('Scheduled meeting with %s') % invitee.name
# VS
message = 'Scheduled meeting with {}'.format(invitee.name) # this is not translated
I have seen some parts of the Odoo code where they have used some workaround, isolating strings.
exc = MissingError(
_("Record does not exist or has been deleted.")
+ '\n\n({} {}, {} {})'.format(_('Records:'), (self - existing).ids[:6], _('User:'), self._uid)
)
But, does anybody know if there is a more convenient way to use the format method and make it work with translations?
_ return a string, so you can call format on it directly.
_("{} Sequence").format(sec.code)
or like this:
_("{code} Sequence").format(code=invitee.code)
when you export the translation in PO file you should see this for the second example:
# for FR translation you should not translate the special format expression
msgid "{code} Sequence"
msgstr "{code} Séquence"
and this for the first example:
msgid "{} Sequence"
msgstr "{} Séquence"
If you don't see this then Odoo must be checking that _() must not be followed by . so you can work around this by doing this for example by surrounding the expression by parentheses :
# I think + "" is not needed
( _("{} Séquence") + "").format(sec.code)
Because In python "this {}".format("expression") is the same as this ("this {}").format("expression")

How to run specified step in SoapUI according testcase result

I have project in soapui with more testcases. After running each testcase I need to run one of two http request, depending on results of steps. So if one or more steps in testcase failed, I need to run httprequest1 and if all steps passed I need to run httprequest2. How can I do this? I have tried many scripts... for now my best solution is something like this, just add groovy script at the end of test case. Problem is that it is checking only last step. I have tried many other solutions, but nothing was working for me. Can somebody help me with this? Thank you
def lastResult = testRunner.getResults().last()
def lastResultStatus = lastResult.getStatus().toString()
log.info 'Test + lastResultStatus
if( lastResultStatus == 'FAILED' )
{
testRunner.gotoStepByName( 'httprequest1' )
testRunner.testCase.testSteps["httprequest2"].setDisabled(true)
}
else
{
testRunner.gotoStepByName( 'httprequest2' )
}
another solution that I have tried:
for( r in testRunner.results )
result = r.status.toString()
log.info result
if( result == 'FAILED' )
{
testRunner.gotoStepByName( 'httprequest1' )
testRunner.testCase.testSteps["httprequest2"].setDisabled(true)
}
else
{
testRunner.gotoStepByName( 'httprequest2' )
}
Like it was mentioned in the comment, and based on the details shared in the comments, Conditional GoTo test step can be used. However, it may required multiple of them. Instead Groovy Script can be the best way in this scenario.
Here are the details assuming the following are the steps in the test case.
Test Case:
request step1
request step2
groovy script step (the proposed script to handle the scenario)
request1 step if above step1 & step2 are successful
request2 step otherwise
following step x
following step y
Here is the pseudo code for the proposed Groovy Script mentioned in #3.
Evaluate the previous test step execution result, like what you currently doing.
Based on the condition, run the test step #4 if true, run step #5 otherwise. Here note that do not use gotoStepByName method, instead run step by its name. See sample #15 here
Once the above if ..else is done, then use gotoStepByName to continue the steps #6, #7 (of course, if any).
NOTE: If gotoStepByName is used to run a step in groovy step, then the control will not come back.
Use a testcase teardown to call the step, since you have to do it for all test cases. The teardown script will look something like this:
if(testRunner.status.toString() == "FAILED"){
testRunner.runTestStepByName( "httprequest1")
println "in if"
}else{
testRunner.runTestStepByName( "httprequest2")
println "in else"
}
Note that you have to use the SoapUI Runner to trigger the testcase / suite and the difference in method being called.

Jenkins: ${BUILD_LOG, maxLines, escapeHtml} not working

I am trying to use "${BUILD_LOG, maxLines, escapeHtml}" like discribed in:
How can I take last 20 lines from the $BUILD_LOG variable?
Unfortunately it doesn't work for me.
I get this error:
Script1.groovy: 114: expecting anything but ''\n''; got it anyway # line 114, column 301.
arted by user MYUSERNAME
My code in this line is:
msg.setText("This build (" + build.getFullDisplayName()
+ " ) contains the following tasks:\n\nTASK\t\t\t IMPLEMENTER:\n"
+ taskList + "\n\n\nLink to this
build: ${BUILD_URL} \n ${BUILD_LOG, maxLines=9999, escapeHtml=false}" );
If I take this out the following, it works. Thats why my guess is, that "BUILD_LOG" is not working anymore?
${BUILD_LOG, maxLines=9999, escapeHtml=false}
EDIT:
Maybe as addition: I am trying to do this withing the PreSend groovy script.
Since I am building the Email text dynamically.
${BUILD_URL} works fine, ${BUILD_LOG, maxLines=9999, escapeHtml=false} doesn't (for me) i am looking for a solution for this...
the msg object is a java MimeMessage.
Thanks,
Daniel
That error message is usually related to not closed quotes, comments started with / instead of //, etc. In your code the only thing I can see is that your third line is not finished properly, i.e., after "\n\n\nLink to this you are not closing double quotes and instead you are starting a new line (thereby the expecting anything but ''\n''.
Try to write the whole line:
msg.setText("This build (" + build.getFullDisplayName()
+ " ) contains the following tasks:\n\nTASK\t\t\t IMPLEMENTER:\n"
+ taskList + "\n\n\nLink to this build: ${BUILD_URL} \n ${BUILD_LOG, maxLines=9999, escapeHtml=false}" );
or close the quotes instead:
msg.setText("This build (" + build.getFullDisplayName()
+ " ) contains the following tasks:\n\nTASK\t\t\t IMPLEMENTER:\n"
+ taskList + "\n\n\nLink to this "
+ "build: ${BUILD_URL} \n ${BUILD_LOG, maxLines=9999, escapeHtml=false}" );
I used the below and it's working fine for me.
${BUILD_LOG, maxLines=10, escapeHtml=false}
I tried with Jenkins version 1.617
Have you tried to set escapeHtml=true? It may happen that this token expanded as is and then string in " " becomes not valid.
In latest version variable ${BUILD_LOG} wasn't available for me - only solution to get log in email content was for me setting:
msg.setText(build.getLog())
as Default Pre-send Script in Jenkins global configuration...

How to use yml file in my cucumber test?

I want to use config.yml file in my cucumber-test. I whrite such like this:
test_config.yml:
group_name: animals
learn_group_name: dogs
card_box_name: cats
cucumber_test.rb:
require `watir-webdriver`
require `yaml`
def read_config
config = YAML.load(File.read(`/home/profile/Desktop/cucumber/test_config.yml`))
#group = config[`group_name`]
#learn_group = config[`learn_group_name`]
#card_box = config[`card_box_name`]
end
puts `Group = #{#group}`
puts `Learn group = #{#learn_group}`
puts `Card box = #{#card_box}`
...
in console (terminal):
Group =
Learn group =
Card box =
...
But what is wrong?
This is a really bad code example.
You are you using backticks (`) instead of quotes ("). That will cause problems. A lot of problems.
The problem is not related to cucumber or watir-webdriver gems. You are defining instance variables (#group...) in a method (read_config) but then you are never calling the method.
Please update the question with more realistic example.
Before do
#host ||= YML["host"]
#group_name_for_search ||= YML["group_name_for_search"]
#learn_group_name_for_search ||= YML["learn_group_name_for_search"]
#card_box_name_for_search ||= YML['card_box_name_for_search']
end
I must to define, before the cucumber steps, Before do.

Puppet iteration string/array

Can you think of a way to solve this problem in Puppet?
I have a custom fact with generates a string of IP addresses depending on the domain it is run on, it can resolve to have 1 to n addresses.
"10.1.29.1"
"10.1.29.1,10.1.29.5"
"10.1.29.1,10.1.29.5,10.1.29.7"
etc
I want to add these to the host file with a generated server names of servernameX for example;
10.1.29.1 myservername1
10.1.29.5 myservername2
10.1.29.7 myservername3
So how can you do this as puppet doesn't have an array iterator like "for each"?
Sadly, even if you go about and use a custom "define" to iterate over an array upon splitting your custom fact on a comma, the result will be rather not what you expect and not even close to a "for each" loop -- aside of causing you a headache, probably.
Said that, I am not sure if this is what you want to achieve, but have a look at this approach:
$fact = '1.1.1.1,2.2.2.2,3.3.3.3'
$servers = split($::fact, ',')
$count = size($servers)
$names = bracket_expansion("host[01-${count}].address")
file { '/tmp/test.txt':
content => inline_template('<%= #servers.each_with_index.map {|v,i| "#{v}\t\t#{#names[i]}\n" } %>'),
ensure => present
}
What we have there are two custom functions: size() and bracket_expansion(); which we then use values that they provide inside a hack that leverages the inline_template() function to render content of the file utilising parallel access to two arrays -- one with IP addresses from your fact and one with host names that should follow.
The result is a follows:
matti#acrux ~ $ cat | puppet apply
$fact = '1.1.1.1,2.2.2.2,3.3.3.3'
$servers = split($::fact, ',')
$count = size($servers)
$names = bracket_expansion("host[01-${count}].address")
file { '/tmp/test.txt':
content => inline_template('<%= #servers.each_with_index.map {|v,i| "#{v}\t\t#{#names[i]}\n" } %>'),
ensure => present
}
notice: /Stage[main]//File[/tmp/test.txt]/ensure: created
notice: Finished catalog run in 0.07 seconds
matti#acrux ~ $ cat /tmp/test.txt
1.1.1.1 host01.address
2.2.2.2 host02.address
3.3.3.3 host03.address
matti#acrux ~ $
Both size() and bracket_expansion() functions can be found here:
https://github.com/kwilczynski/puppet-functions/tree/master/lib/puppet/parser/functions/
I hope this helps a little :-)

Resources