Robot framework: variable function with dictionary arguments - variables

I have a variable file which defines a variable like dictionary in dictionary and variable functions.
global.py
DEFAULT_VAL=111
TEST_VAR={'key1':{'elem1':'val1', 'elem2':'val2', 'elem3':'val3'}, 'key2':{'elem2':'val2', 'elem3':'val3'}}
def get_elem1_or_default_1(key):
return TEST_VAR[key]['elem1'] if 'elem1' in TEST_VAR[key] else DEFAULT_VAL
def get_elem1_or_default_2(key_dict):
return key_dict['elem1'] if 'elem1' in key_dict else DEFAULT_VAL
From robot I can call variable function 'get_elem1_or_default_1' which accept string as key, like this:
*** Settings ***
Variables Global.py
${var} Set variable ${get_elem1_or_default_1('key2')}
INFO : ${var} = 111
But when I try to call another function 'get_elem1_or_default_2' which accept dict as argument I get an error
${key_dict} Evaluate ${TEST_VAR}['key1']
${var} Set variable ${get_elem1_or_default_2(${key_dict})}
INFO : ${key_dict} = {'elem2': 'val2', 'elem3': 'val3', 'elem1': 'val1'}
FAIL : Invalid variable name '${get_elem1_or_default_2({'elem2': 'val2', 'elem3': 'val3', 'elem1': 'val1'})}'.
Is it possible to do so or something is wrong? May be there is another way?
Thanks!

Your "variable functions" are just functions that should be called as keywords and not as variables. So you you can keep your global.py as it is, but call your functions this way:
*** test cases ***
mytest
${key_dict} = Evaluate ${TEST_VAR}['key1']
${var} = get_elem1_or_default_2 ${key_dict}

Related

Godot/Gdscript: Why is str2var not working on classes with _init method?

Let's define 2 classes
A.gd
class_name A
var v = null
func _init(v_):
v = v_
B.gd
class_name B
var v = null
Now, when I try to use str2var/var2str, this is what I get
var a = A.new("aaa")
var b = B.new()
b.v = "bbb"
printt("var2str(a):", var2str(a))
printt("var2str(b):", var2str(b))
printt ("var2str(str2var(var2str(a))):", var2str(str2var(var2str(a))))
printt ("var2str(str2var(var2str(b))):", var2str(str2var(var2str(b))))
Output:
var2str(a): Object(Reference,"script":Resource( "res://Scripts/AI/A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":null)
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
Why is str2var(a) not working?
How should I fix it?
The Solution
Fix it by making the parameter optional, for example:
class_name A
var v = null
func _init(v_ = null):
v = v_
With that there is no error. I get this output:
var2str(a): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
The problem
For abstract, str2var will not pass any arguments to _init. It would not know what to pass anyway.
The rest of the answer is the process of confirming that str2var will result in calling _init with no argument.
When I try your code I get this error:
E 0:00:00.630 _create_instance: Condition "r_error.error != Variant::CallError::CALL_OK" is true. Returned: __null
<C++ Source> modules/gdscript/gdscript.cpp:121 # _create_instance()
<Stack Trace> main.gd:12 # _ready()
We can find the line that throws the error in _create_instance by looking at the source.
Sadly that does not give me much information. So, I decided to search how str2var is implemented.
We find it inside GDScriptFunctions::call, here. Which calls VariantParser::parse, which calls VariantParser::parse_value. We are interested in the case of an "Object" (here). And that results in a call to ClassDB::instance(type). There type will be "Reference", and then it procedes to set all properties as they come. Being the first one "script":Resource("res://A.gd").
When we set the script (here), it will result in a call to GDScript::instance_create. Which calls GDScript::_create_instance (here):
return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error)
With no argument for _init (The NULL is the argument array, and 0 is the number of arguments). This is the signature for GDScript::_create_instance:
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error)
Of course, initializer->call(instance, p_args, p_argcount, r_error); fails, because _init requires an argument. And we find the line that throws the error further down. Note: initializer is created while parsing the script.

Terraform: Set optional resource attribute if condition is met, otherwise don't declare it

Some resources on Terraform support optional attributes. I'm interested in declaring and setting a value for the optional attribute only if a condition is met. Otherwise, don't declare it at all.
All of the suggestions I found was based on declaring the attribute and setting its value to null if the condition isn't satisfied, instead of not declaring the attribute at all.
Is there a way for me to do something like the following? In pseudo-code:
resource "some_resource" "this" {
name = var.name
if var.name == "some_name":
some_optional_attribute = "some_value"
else:
pass # do nothing, don't even declare the optional attribute
}
Let me know, thanks in advance!
I don't believe there is a better method than simply doing the following:
resource "some_resource" "this" {
some_optional_attribute = var.name == "some_name" ? var.name : null
}
When you declare attribute as null that basically means that it is not being used. The above in my opinion is equivalent to your if statement.

warning variable unused in assert

I can test the content after a redirection like this
assert "/url" = redir_path = redirected_to(conn, 302)
conn = get(recycle(conn), redir_path)
assert html_response(conn, 200) == "Content after redirection"
But I cannot add a param variable to the assert url like this:
id = 10
assert "/url/#{id}" = redir_path = redirected_to(conn, 302)
It complains with:
cannot invoke remote function id/0 inside match
So if I just define the path like this before using it:
url_path = "/url/%{id}"
assert url_path = redir_path = redirected_to(conn, 302)
warning: variable "url_path" is unused
?? unusued? is it being used inside the assert...
Not sure how to silence that warning or how to approach this.
The code is similar to Chris's response here:
https://elixirforum.com/t/following-redirection-in-controllertests/10084
warning: variable "url_path" is unused
?? unusued? is it being used inside the assert...
No, it's not. Your assert will match any value because if you have a variable name on the LHS of a match, it matches any value and that variable gets assigned the value of the RHS.
In:
foo = 10
assert foo = 20
IO.inspect foo
the assert passes and foo is printed as 20.
If you just want to assert that that string equals the value returned by redirected_to/2, you can use ==:
assert "/url/#{id}" == redirected_to(conn, 302)

Call SQL stored procedure with named parameter in Groovy

private static String XXX = "{call SP_XXX(?,?,?)}"
sql.call (XXX, [Sql.NUMERIC, Sql.NUMERIC,'SOME STRING'){
outPara1, outPara2 ->
log.info("${outPara1}, ${outPara2}")
}
I am able to call the stored procedure successful with the above code.
But, when I am using named parameters instead of '?' placeholder.
I am getting:
WARNING: Failed to execute: {call SP_XXX(:OUTP1, :OUTP2, :INP1)}
because: Invalid column type
What I changed is replaced the '?' with ":OUTP1", "OUTP2" and ":INP1".
And in the call statement, using the named parameters accordingly.
The code after change:
private static String XXX = "{call SP_XXX(:OUTP1, :OUTP2, :INP1)}"
sql.call (XXX, [OUTP1: Sql.NUMERIC, OUTP2: Sql.NUMERIC, INP1: 'SOME STRING']){
outPara1, outPara2 ->
log.info("${outPara1}, ${outPara2}")
}
What you are doing is passing a map to call() which I do not think we have an api for. Moreover, the placeholders for the SP has to be ?.
Either you can stick to your former approach or try using GString as below:
def inp1 = 'SOME STRING'
sql.call "{call SP_XXX(${Sql.NUMERIC}, ${Sql.NUMERIC}, $inp1)}", {
outPara1, outPara2 ->
log.info("${outPara1}, ${outPara2}")
}
I would prefer the former approach instead. :-)

z.Repeat.Once not working

I'm using Rhino Mocks to write my Unit Tests and I'd like to use Assert.WasCalled functionality, but I'm keep getting an error.
My help method used by a bunch of tests:
Private Function CreateSecurityTicketHelper(userName As String, validFrom As DateTime, validTo As DateTime) As ISecurityTicket
' Prepare a mock object for ITicketingDataManager interface
Dim dataManagerMock = MockRepository.GenerateMock(Of ITicketingDataManager)()
' Prepare a mock function for ITicketingDataManager.InitializeNewTicket(string, string)
Dim returnSecurityTicket As Func(Of String, String, ISecurityTicket) = Function(u, k) New SecurityTicketEntity() With {.UserName = u, .Key = k}
dataManagerMock.Stub(Function(x) x.InitializeNewTicket(Nothing, Nothing)).IgnoreArguments().Do(returnSecurityTicket)
' Create new TicketingManager instance
Dim ticketingManager = New TicketingManager(dataManagerMock)
' Try creating new security ticket
Dim ticket = ticketingManager.CreateSecurityTicket(userName, validFrom, validTo)
' Check if proper ITicketingDataManager method was invoked
dataManagerMock.AssertWasCalled(Sub(x) x.InitializeNewTicket(Nothing, Nothing), Sub(z) z.Repeat.Once())
' Return the ticket
Return ticketingManager.CreateSecurityTicket(userName, validFrom, validTo)
End Function
I can debug that method and all goes right until AssertWasCalled method is called, when I'm getting following exception:
Test method
Authentication.UnitTests.TicketingManagerTests.CreateSecurityTicket_ValidUserNameAndKey_TicketIsCreated
threw exception:
Rhino.Mocks.Exceptions.ExpectationViolationException:
ITicketingDataManager.InitializeNewTicket(null, null); Expected #1,
Actual #0.
Your assertion says that InitializeNewTicket() method should be called once with arguments (Nothing, Nothing).
If this method is being called with some another arguments then assertion fails.
You have to rewrite assertion to either A) accept any arguments or B) specify correct arguments.
See examples below.
Few notes about examples:
1. Ufortunatelly I'm not good in VB syntax so providing examples in C#.
2. It is not mentioned in question which parameters type has method InitializeNewTicket() so for example I assume it has String parameters.
To accept any parameters in assertion:
dataManagerMock.AssertWasCalled(
x => x.InitializeNewTicket(Arg<String>.Is.Anything, Arg<String>.Is.Anything),
z => z.Repeat.Once());
To specify expected arguments (e.g. expected1, expected2):
dataManagerMock.AssertWasCalled(
x => x.InitializeNewTicket(Arg<String>.Is.Equal(expected1), Arg<String>.Is.Equal(expected2)),
z => z.Repeat.Once());
Hope that explains the reason of your issue and helps to solve :).