What is the Spinnaker pipeline expression for the current stage? - spring-el

I'm trying to write a Spinnaker pipeline expression that determines some criteria based on the current stage and its ancestors. Per the documentation, you can use the #root helper to get the current stage context; however, it doesn't appear there is any way to get the current stage.
For example, if you wanted to find out if the current stage has any ancestors that have a failure status, right now you have to know the stage name, which seems counter-intuitive given the existence of #root.
${ #stage("My Stage").ancestors().?[status.isFailure() && name != "My Stage"] }
I'd like to replace the #stage("My Stage") with something similar to #root however, again #root is the context object inside the stage, not the stage itself.
Note it also appears the Stage.ancestorsOnly() method is private at the moment so if you want to find only ancestors that have failed (or have some other criteria) you need to manually exclude the current stage. That's why I have the extra name comparison in there.

root and #this in SPEL are just aliases for when you need to reference the current object used in places like filters, I wouldn't get too caught up with it.
Maybe the right thing here is to add a few more values to the augmented context we evaluate SPEL against https://github.com/spinnaker/orca/blob/7de225679cf19cbcbfcfdbdcd08dc1962247f0fe/orca-core/src/main/java/com/netflix/spinnaker/orca/pipeline/util/ContextParameterProcessor.java#L90 to include values such as stage id so it would be easier to add helper functions like #currentStage() or #ancestorStaget() here https://github.com/spinnaker/orca/blob/fc87a8e99ec59a4e129646026987aa5adbde2d31/orca-core/src/main/java/com/netflix/spinnaker/orca/pipeline/expressions/ExpressionsSupport.java#L60
There are subtle issues here because stage expressions get evaluated before a stage runs so for static values like ancestors it should be ok, but for values like status the value you get will not be updated

Related

How do I access value of a selected <option> tag down 2 trees in a function?

PizzaBuilder1.js
Ingredients.js
Bases.js
PizzaBuilder2.js
PizzaBuilder3.js
I'll try to describe my issue in the least confusing way. So what I'm trying to achieve is create a function(pic4-PizzaBuilder2), where I compare the given key of this.state.ingredients.Bases (and other sub-objects, but that's not important for now) with value of selected option tag in Bases.js and when it matches, set the given value of that key to true. The hierarchy is like this: PizzaBuilder.js > Ingredients.js > Bases.js. I have already managed to match each option value with the key inside the object with the same name. However, what I'm still struggling with is how to access it in PizzaBuilder.js when the select option value I wanna compare it to is 2 trees down (see pic4-PizzaBuilder2, that is supposed to be const selectedOption, but I obviously still need to figure out how to access it). I'll be really grateful for any kind of advice.

estudio does not check `require` when it should?

Eiffel Studio seems to pass through my requirements even if I have them enabled on project settings. And as far as I remember I was able some time to put a break point into the requirements...
I don't understand what I'am missing here, as you can see in my example, the requirement passes through as I have the same condition on the code and it goes into (attached {POWER_DEVICE} a_csv.device as l_dev).
A general rule for inherited assertions is the following:
preconditions can be only relaxed;
postconditions can be only strengthened.
In the particular example the effective precondition is
True
or else
valid_csv (a_csv) and then attached {POWER_DEVICE} a_csv.device
This is reflected by the keywords require at the beginning and require else in the middle of the combined precondition in the flat form of the feature. The expression True is inherited. This is the precondition of the feature in the parent.
A possible solution is to move valid_csv (a_csv) to the parent feature, and redefine valid_csv in the descendant. If valid_csv is common for all calls, but the second test varies across descendants, it might be better to introduce a new feature is_known and have 2 precondition subclauses in the parent:
is_valid_csv: is_valid_csv (a_csv)
is_known_csv: is_known_csv (a_csv)
The implementation of is_known_csv in the class POWER_CSV_PROCESSOR would be
is_known_csv (a_csv: ...)
do
Result := attached {POWER_DEVICE} a_csv.device
end
and the precondition of feature process in POWER_CSV_PROCESSOR would be empty.
The caller would then do something like
if processor.is_known_csv (csv) then
processor.process (csv)
end

How do I select whether the routine continues based on the participant's response?

I want to create an experiment in PsychoPy Builder that conditionally shows a second routine to participants based on their keyboard response.
In the task, I have a loop that first goes through a routine where participants have three options to respond ('left','right','down') and only if they select 'left', regardless of the correct answer, should they see a second routine that asks a follow-up question to respond to. The loop should then restart with routine 1 each time.
I've tried using bits of code in the "begin experiment" section as such:
if response.key=='left':
continueRoutine=True
elif response.key!='left':
continueRoutine=False
But here I get an error saying response.key is not defined.
Assuming your keyboard component is actually called response, the attribute you are looking for is called response.keys. It is pluralised as it returns a list rather than a single value. This is because it is capable of storing multiple keypresses. Even if you only specify a single response, it will still be returned as a list containing just that single response (e.g. ['left'] rather than 'left'). So you either need to extract just one element from that list (e.g. response.keys[0]) and test against that, or use a construction like if 'left' in response.keys to check inside the list.
Secondly, you don't need to have a check that assigns True to continueRoutine, as it defaults to being True at the beginning of a routine. So it is only setting it to False that results in any action. So you could simply do something like this:
if not 'left' in response.keys:
continueRoutine = False
Lastly, for PsychoPy-specific questions, you might get better support via the dedicated forum at https://discourse.psychopy.org as it allows for more to-and-fro discussion than the single question/answer structure here at SO.

Unable to identify object using descriptive programming but able to do so with description object

On my application i have to search for an alphanumeric id which return one or more rows of data. On each of these rows a link is present i have to click on the first link.
Unfortunately it doesn't have any unique properties so i cannot add it to the OR. Instead i used descriptive programming something like below
'returns false
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A").Exist
QTP fails to identify the object with the above code. So Instead of this i tried using Description object something like the below code
Set oDesc = Description.Object
oDesc("class").Value = "ng-binding"
oDesc("html tag").Value = "A"
oDesc("innertext").Value = "AplhaID"
Set lnk = page.ChildObjects(oDesc)
'gives me 2 which is correct. There are two links
msgbox lnk.Count
'highlights the correct link
lnk(0).Highlight
I do not know what could be causing this behavior. I thought is could be because multiple links match the description but I perform this search for multiple ids and eventhough multiple rows are returned the descriptive programming code is able to identify the correct row and proceed.
I looked at QTP descriptive programming issue but my link's property values do not have special characters.
In order to use Descriptive string method, ensure that you have only one object matching the given properties.
Below statement might fail if there are more than 1 object with the given properties.
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A").Exist
So , you need to make the statement to find an object uniquely. Try this. It will work!
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A", "index:=0").Exist

Declaring tables in Slick

I've been getting errors when trying to do many-to-many relations in Slick. This test shows how to do many-to-many relations in Slick. I followed it but then go this error:
Select(TableNode, "id") found. This is typically caused by an attempt to use a "raw" table object directly in a query without introducing it through a generator
I then found out that this is caused by declaring your tables at a static location (an object) and then trying to import it (it works fine if the object is in the same block). http://slick.typesafe.com/doc/1.0.0/lifted-embedding.html#tables
Ok, so val T = new Table inside of an object is the answer. But now I'm getting this error:
recursive method bs needs result type
It doesn't need a result type if it is an object and not a val. I've heard of using a class but I can't find any examples on how to do this.
How do you declare many-to-many models and import them from somewhere else?
EDIT:
Here's a gist showing what I mean: https://gist.github.com/pjrt/5332311
If you run the first test, it will pass, no issue.
If you run the second test, the following error is thrown:
scala.slick.SlickException: Select(TableNode, "id") found. This is typically caused by an attempt to use a "raw" table object directly in a query without introducing it through a generator.
If you run the third test (using vals inside of objects instead of objects directly), you get this error:
recursive method bs needs result type
[error] val A = new Table[(Int, String)]("a") {
recursive value AToB needs type
[error] def as = AToB.filter(_.bId === id).flatMap(_.aFK)
I know why the errors are happening, but I want to know how people got around them. One way is to put the objects inside of a class and instantiating a class every time you want to use Slick (but this seems...weird). Another is to never use Slick-related stuff outside of the package (or at least many-to-many stuff) but that also seems bad.
My question, still is, how do you guys get around this? Is there a proper way?
The error message you showed makes me think that you defined your tables but tried to access them directly instead of using a for comprehension.
The test file you were referring has an example right at the bottom, after defining the many-to-many tables that goes like
val q1 = for {
a <- A if a.id >= 2
b <- a.bs
} yield (a.s, b.s)
q1.foreach(x => println(" "+x))
assertEquals(Set(("b","y"), ("b","z")), q1.list.toSet)
What you see is that object table A is used as a comprehension generator (i.e. a <- A)
Does your code access the tables in some other way?

Resources