Origen test_ids next in range accept a Proc/Lambda? - origen-sdk

I am working with the Origen test_ids gem 'next in range' feature. When I setup the softbin configuration in the test interface I find out dynamically how many different hardbins have a unique softbin range. This is known but it varies depending on the test module being tested. Some test modules may have 3 hardbin to softbin combinations and some have 5. Is it possible to pass a Proc/Lambda to the softbin config shown below?
config.softbins needs: :bin do |options|
    if options[:bin] == 1
      TestIds.next_in_range((1000..2000))
    elsif options[:bin] == 11
      TestIds.next_in_range((10000..99999))
    end
  end
Such that the number of elsif statements, the bin and the softbin range are all dynamically stitched together. I know eval could work but it seems to be frowned upon.
EDIT
OK after reviewing Ginty's answer I tried the solution but it seems like the options are not getting passed into the next_in_range method. Here is the config:
TestIds.configure current_test_insertion do |config|
config.bins.include << binning_obj.configs(:all).hbin
config.softbins needs: :bin do |options|
bin_map = Hash[test_type_hardbins.zip(binning_test_types)]
TestIds.next_in_range(bin_map[options[:bin]])
end
config.send_to_ate = false
end
Here is the error:
COMPLETE CALL STACK
-------------------
wrong number of arguments (given 1, expected 2)
/users/user/origen/github/test_ids/lib/test_ids.rb:236:in `next_in_range'
When I pass in the options as so:
TestIds.next_in_range(bin_map[options[:bin]], options)
I get this error:
COMPLETE CALL STACK
-------------------
undefined method `map' for nil:NilClass
Did you mean? tap
/users/user/origen/github/test_ids/lib/test_ids/allocator.rb:45:in `range_item'
/users/user/origen/github/test_ids/lib/test_ids/allocator.rb:32:in `next_in_range'
Given that the docs say this feature is in beta, should I move this to a Github issue?
thx

When defining a softbin with a block, you have complete freedom to put whatever you want in the block, so adding an additional Proc into the equation doesn't make sense to me.
There are effectively two APIs here that you can combine, one is the ability to define a function to work out the number:
config.softbins do |options|
# Put any logic you like in here, return the number at the end
end
The other API is the ability to have TestIds keep track of a position in a range:
TestIds.next_in_range((1000..2000))
You can use that, or not, within your block however you wish.
That you should give you full freedom to define whatever rules you like:
config.softbins needs: bin do |options|
if Time.now.tuesday?
bin_map = { 5: (1..10), 11: (11..20) }
else
bin_map = { 6: (10..20), 12: (21..30) }
end
TestIds.next_in_range(bin_map[options[:bin]])
end
Note that if you refer to the same next_in_range within different branches then they will both consume from the same set of numbers.
If you wanted them to each independently count within that range, then you would need to setup different configurations so that they each have their own database:
if Time.now.tuesday?
TestIds.configure :rule1 do |config|
end
else
TestIds.configure :rule2 do |config|
end
end

Related

How can I define template to command in lua into variable?

i'm trying to do something like that:
get_num_of_ones = "('1'):rep(%d)"
print(get_num_of_ones:format(24))
but i get the following result: ('1'):rep(24) and not 24 times the number 1.
how can I do it in this way so that i will get 111...11 (24 times the number 1) ?
The simplest, most straightforward, efficient and readable way to achieve what you want is simply to pass your number directly to string.rep; there is no need to format source code here:
get_num_of_ones = ('1'):rep(24)
print(get_num_of_ones)
If there is the artificial constraint that it needs to be achieved by formatting a source code template, you need to use load/loadstring:
get_num_of_ones = "return ('1'):rep(%d)" -- you need the "return" to make it a valid chunk, and to be able to get the result out
local source = get_num_of_ones:format(24) -- formatted source code
local chunk = assert(load(source)) -- load the source code; gives us a "chunk" (function) if there was no syntax error
local retval = chunk()
print(retval)

How to test the value of ensure in a custom type?

I've been writing custom types for Puppet, and I've run into a case where for both 'latest' and 'present' I require the existence of certain parameters, but for 'absent' I would like those parameters to be optional.
Unfortunately, I haven't been able to figure out how to test the value of 'ensure' within the ruby code.
Puppet::Type.type(:fubar) do
ensurable do
desc 'Has three states: absent, present, and latest.'
newvalue(:absent) do
# ...
end
newvalue(:latest) do
# ...
end
newvalue(:present) do
# ...
end
def insync?(is)
# ...
end
defaultto :latest
end
# ...
validate do
# This if condition doesn't work. The error is still raised.
if :ensure != :absent
unless value(:myprop)
raise ArgumentError, "Property 'myprop' is required."
end
end
end
end
So, my question is simple... How do I test the value of 'ensure' so that when it is 'absent', the validation is NOT performed?
Thanks to both Matt Schuchard and John Bollinger for their help.
The problem is that:
if :ensure != :absent
is indeed comparing two symbols, where I need to be comparing the value of a property to a symbol:
if self[:ensure] != :absent
I am sufficiently new to both Puppet and Ruby that I didn't realize the difference. John stated it clearly, and Matt provided a good example.
Again, Thanks to both Matt and John.

Spock label combinations

There | are | so many | Spock | spec examples of how to use its labels, such as:
// when -> then label combo
def "test something"() {
when:
// blah
then:
// blah blah
}
Such label combinations as:
when -> then
given -> when -> then
expect
given -> expect
But nowhere can I find documentation on what the legal/meaningful combinations of these labels are. For instance, could I have:
def "do something"() {
when:
// blah
expect:
// blah
}
Could I? I do not know. What about:
def "do something else"() {
when:
// blah
then:
// blah
expect:
// blah
where:
// blah
}
Could I? Again, I do not know. But I wonder.
I am actually an author of one of the tutorials you have mentioned. I think the best to answer your question would be to really understand what particular labels are for. Maybe then it would be more obvious why certain combinations make sense and other do not. Please refer to original documentation http://spockframework.github.io/spock/docs/1.0/spock_primer.html. It explains really well all labels and their purpose. Also it comes with this diagram:
Which I hope should already tell you a lot. So for instance having both when and expect labels makes not much sense. The expect label was designed to substitute both when and then. The reasoning behind it is well explained in the documentation:
An expect block [...] is useful in situations where it is more natural to describe stimulus and expected response in a single expression.
Spock itself will not allow you to use this combination. If you try to execute following code.
def "test"() {
when:
println("test")
expect:
1==1
}
You will receive an error message like this.
startup failed:
/Users/wooki/IdeaProjects/mylibrary/src/test/groovy/ExampleTest.groovy:
13: 'expect' is not allowed here; instead, use one of: [and, then] #
line 13, column 9.
To my surprise the second of your examples works. However I believe there is really not much gain of using expect here instead of and as I would normally do.
def "do something else"() {
when:
// stimulus
then:
// 1st verification
and:
// 2nd verification
where:
// parametrization
}
The only reason to have expect or and after then is to separate code responsible for verifying the result of executing the code inside when label. For instance to group verifications that are somehow related to each other, or even to separate single verifications but to have a possibility of giving them a description using strings that can be attached to labels in Spock.
def "do something else"() {
when:
// stimulus
then: "1 is always 1"
1 == 1
and: "2 is always 2"
2 == 2
}
Hence, since you are already stating that verification part of the test began (using then block) I would stick to and label for separating further code.
Regarding where label. It works sort of as a loop indicator. So whatever combinations of labels you use before you could always put at the end the where label. This one is not really a part of a single test run, it just enforces the test to be run a number of times.
As well it is possible to have something like this:
def "test"() {
given:
def value
when:
value = 1
then:
value == 1
when:
value = 2
then:
value == 2
}
Using the above, just make sure that your test is not "testing too much". Meaning that maybe a reason why you use two groups of when-then makes a perfect excuse for this test to be actually split into two separate tests.
I hope this answered at least some of your questions.

Is it possible to skip loading a row using the kiba-etl gem?

Is there a way I can skip loading certain rows if I deem the row invalid using the kiba-etl gem?
For example, if there is a validation that must be passed before I load it into the system or errors that occur and I still need to push the data into to sys regardless while logging the problem.
Author of Kiba here! To remove a row from the pipeline, simply return nil at the end of a transform:
transform do |row|
row_valid = some_custom_operation
row_valid ? row : nil
end
You could also "write down" the offending rows, and report on them later using a post_process block like this (in this case, require a moderate to low number of bogus rows):
#bogus_row_ids = []
transform do |row|
# SNIP
if row_valid(row)
row
else
#bogus_row_ids << row[:id]
nil # remove from pipeline
end
end
post_process do
# do something with #bogus_row_ids, send an email, write a file etc
end
Let me know if this properly answers your question, or if you need a more refined answer.
I'm dumb. I realized you can just catch your errors within the transformation/loading process and return nil.

writing an excel formula with multiple options for a single parameter

I would like to access information from a HTTP based API and manipulate it with excel.
The API returns about 20 pieces of information, and you can get that information by looking up any number of about ten lookup fields: name, serial number etc.
I want to write a function similar to the Match Function in excel where one of the parameters (in this case MATCH TYPE) has multiple possible values.
I have a list of values (the 20 pieces of information the API can return) and I want to make these pieces of information the possible return values for one of the Functions parameters.
How do I do I create a function where one parameter has a list of possible values?
And how do I add tooltip help statements to those parameter options so people know what they are?
You want to use an Enum.
In the declarations part of your module (before any subs or functions) you can place code like this.
Enum MyFunctionsArgValue
LessThan
Equal
GreaterThan
End Enum
This will assign each of these keywords an integer value, starting at zero and counting up. So LessThan = 0, Equal = 1, and GreaterThan = 2. (You can actually start at any number you want, but the default is usually fine.)
Now you can use it in your function something like this.
Function MySuperCoolFunction(matchType as MyFunctionsArgValue)
Select Case matchType
Case LessThan
' do something
Case Equal
' do it different
Case GreaterThan
' do the opposite of LessThan
End Select
End Function
To get the tool tip, you need to use something called an Attribute. In order to add it to your code, you'll need to export the *.bas (or *.cls) file and open it in a regular text editor. Once you've added it, you'll need to import it back in. These properties are invisible from inside of the VBA IDE. Documentation is sketchy (read "nonexistent"), so I'm not sure this works for an Enum, but I know it works for functions and module scoped variables.
Function/Sub
Function MySuperCoolFunction(matchType as MyFunctionsArgValue)
Attribute MySuperCoolFunction.VB_Description = "tool tip text"
Module Scoped Var
Public someVar As String
Attribute someVar.VB_VarDescription = "tooltip text"
So, you could try this to see if it works.
Enum MyFunctionsArgValue
Attribute MyFunctionsArgValue.VB_VarDescription = "tool tip text"
LessThan
Equal
GreaterThan
End Enum
Resources
https://www.networkautomation.com/automate/urc/resources/help/definitions/Sbe6_000Attribute_DefinintionStatement.htm
http://www.cpearson.com/excel/CodeAttributes.aspx

Resources