Can I use an oozie action as a template that I call many times? - oozie

I have a shell oozie action that takes in a number of arguments that get passed to the shell script. I want to trigger that action multiple times with different arguments each time. An example dag would look something like:
Start
/ | \
f(a) f(d) f(g)
| | |
V V V
f(b) f(e) f(h)
| | |
V V V
f(c) f(f) f(i)
\ | /
End
Is it possible to achieve this without having a bunch of duplicate actions?

yes, it is possible with Oozie sub-workflow option.
Compose the Shell action as a sub-workflow and call the sub-workflow from many places from the main workflow with different input values.
<action name="call_sub_workflow_1">
<sub-workflow>
<app-path>${workflowAppUri}/sub_workflow_with_shell_action/</app-path>
<propagate-configuration/>
<configuration>
<property>
<name>argument_1</name>
<value>${wf:actionData('previous_action')['val1']}</value>
</property>
<property>
<name>argument_2</name>
<value>${val2}</value>
</property>
</configuration>
</sub-workflow>
<ok to="End"/>
<error to="Fail"/>
</action>
Main workflow with sub-workflow directory structure will looks like,
main_workflow_dir
|
|--job.properties
|
|--workflow.xml # main workflow, can call sub workflow from multiple places
|
|--sub_workflow_with_shell_action
|
|--shell script
|
|--workflow.xml # sub workflow contains the shell script action and takes arguments

Related

Complete a command (with arguments) like another command (with other arguments)

compdef cmd1=service can be used to define a completion alias, however, that works only when the arguments are going to be the same.
For example, consider a helper script which rewrites some arguments before executing another command:
| What is typed | What is executed |
|---------------+----------------------------|
| s | systemctl |
| s q | systemctl status |
| s q foo | systemctl status foo |
| s j foo | journalctl --unit foo |
| s r foo | sudo systemctl restart foo |
We can ask the script to print the arguments it would execute, so e.g. PRINT_ONLY=1 s would print just systemctl.
Assuming completion is already set up for systemctl / journalctl / sudo, how would one define a zsh completion for such a script? Rather than redundantly reimplementing completion for those commands, how to implement completion for s such that the completion system is invoked with a transformed command -- i.e. something like function _s() { get_completions $(PRINT_ONLY=1 s "$#") ; }?
This should go in a file named _s somewhere on your $fpath:
#compdef s
local -a orig_command new_words
orig_command=("${words[#]}")
if [[ $words[-1] == '' ]]; then
# remove an empty word at the end, which the completion system cares about
orig_command[-1]=()
fi
# split the rewritten command into words using the shell parser
new_words=("${(z)$(PRINT_ONLY=1 "${orig_command[#]}")}")
if [[ $words[-1] == '' ]]; then
# restore the empty word if we removed it
new_words+=('')
fi
# update the cursor position
CURRENT=$(( CURRENT - $#words + $#new_words ))
words=("${new_words[#]}")
# restart completion with the rewritten command
_normal
Note: this doesn't do any error handling and just assumes that any unknown arguments will be passed to the default command (e.g. s start foo -> systemctl start foo). If that's not the case, let me know how s behaves in those cases and I can update the completion script.

Is there a way to verify that given targets are marked .PHONY in makefile?

I am having a bunch of make files in different projects that I want to verify against some criteria of all targets or a list of targets are marked .PHONY.
I am not sure whether such a test already exists or if it is possible to introduce one?
As far as I'm aware, no.
make / gmake itself has no functionality to print that.
However, it's easy to find out yourself from make's dependency/target database output:
make -nsp --no-print-directory --always-make
||| | |
||| | run, no matter whether
||| | parts have already been built
||| |
||| don't print the directory structure
|||
||\--- print the database
|\---- be silent, otherwise
\----- don't actually build anything
prints what make figured out are all targets.
make -nsp --no-print-directory --always-make | grep -E '^\.PHONY:'
prints all the targets that are dependencies of the .PHONY "pseudo"-target.
You can then do with that list whatever you want :)

Log in console Gherkin steps with Robot Framework

I want to use Robot Framework to write and execute Test Cases in Gherkin format.
What I want is when I execute a Test Case, output in the console besides the name
of the Scenario, each step (When, Then...) and log as well if the step passes or not.
You could achieve such functionality with a listener that uses the listener interface of the framework.
The end_keyword listener method will be invoked during execution when a keyword is finished. It will get the keyword name and its attributes as a parameter, so you can log both the name and the status.
You have to filter it so only keywords starting with Given, When, Then will be logged on the console.
Example:
ROBOT_LISTENER_API_VERSION = 2
def start_test(name, attributes):
# Add an extra new line at the beginning of each test case to have everything aligned.
print(f'\n')
def end_keyword(name, attributes):
if name.startswith('Given') or name.startswith('When') or name.startswith('Then'):
print(f'{name} | {attributes["status"]} |')
Console output for the behavior-driven development example of the user guide.
robot --pythonpath . --listener listener.py test.robot
==============================================================================
Test
==============================================================================
Add two numbers
Given I have Calculator open | PASS |
.When I add 2 and 40 | PASS |
.Then result should be 42 | PASS |
Add two numbers | PASS |
------------------------------------------------------------------------------
Add negative numbers
Given I have Calculator open | PASS |
.When I add 1 and -2 | PASS |
.Then result should be -1 | PASS |
Add negative numbers | PASS |
------------------------------------------------------------------------------
Test | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================

Looping in Robot framework

I would like to repeat the similar commands with replacing few variables in Robot framework. Could please suggest me how to do it?
Here is the sample code:
variable1 = ['abc']
varaible2 = ['123','456']
| | Run Keyword And Continue On Failure | testing | ${variable1} | ${variable2} | ${GetVal} | ${Check} |
variable3 = ['xyz']
varaible2 = ['678','789']
| | Run Keyword And Continue On Failure | testing | ${variable3} | ${variable4} | ${GetVal} | ${Check} |
Yes Robot framework supports for loops here is the example
:FOR ${animal} IN cat dog
\ Log ${animal}
\ Log 2nd keyword
Log Outside loop
For More Examples Please go through this link
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#for-loops
Robot framework provides a "for" loop with the special keyword :FOR (see For Loops in the user guide)
| | :FOR | ${v2} | IN | #{variable2}
| | | Run keyword and continue on failure
| | | ... | testing | ${variable1} | ${v2} | ${GetVal} | ${Check}
Notice that the body of the loop has an extra level of indentation.
If you want to do nested loops you'll need to create a separate keyword for the nested loop. It very quickly becomes easier to write a single python keyword that does all of the looping and logic, as robot really isn't designed to be a general purpose programming language.
here is an example which loops for a given number
: FOR ${INDEX} IN RANGE 200
\ Log To Console ${INDEX}
The other answers are very good at explaining how to write a simple FOR loop in Robot Framework, so this is added clarity for your information.
First of all, the code to do as you're asking is as follows, assuming the various unknown variables are already defined elsewhere:
*** Test Cases ***
Do Your Test
:FOR ${INDEX} IN RANGE ${INCLUSIVE_STARTING_INDEX1} ${EXCLUSIVE_ENDING_INDEX1}
\ Run Keyword and Continue On Failure testing ${variable1} ${variable2} ${GetVal} ${Check}
:FOR ${INDEX} IN RANGE ${INCLUSIVE_STARTING_INDEX2} ${EXCLUSIVE_ENDING_INDEX2}
\ Run Keyword and Continue On Failure testing ${variable3} ${variable4} ${GetVal} ${Check}
Second, I need to clarify that FOR Loops in Robot Framework are NOT Keywords. They're distinctively separate entities at the most basic level in the language. I learned this by spending hours delving into the code, trying to figure out how it might be possible to code a nestable For loop. To save you the effort of trying, it isn't without coding your own customized keyword in Python.
Also, I should specify that I'm taking the liberty of assuming that you made a few typos in your question, and that your personalized keyword "testing" that you wrote somewhere else accepts a list object as its second input variable. If that is incorrect, let me know and I'll give you a more accurate answer.
If you want only one loop you can use
:FOR ${iTemp} IN #{listOfStudents}
\ Log ${iTemp}
\ Log GO_ON.
but you can't make loop inside loop
for that you should use keyword for that like below
First Loop
:FOR ${i} IN #{listOfStudents}
\ Log ${i}
\ Log OutSide Loop
Outside Loop
:FOR ${j} IN #{ListOfSubject}
\ Log ${j}
\ Log new Kewords.
Thats the way you can use loops in Robot Framework
Thasnks
For loop syntax was enhanced in Robot Framework 3.1. New syntax is as follows:
*** Test Cases ***
Example
FOR ${animal} IN cat dog
Log ${animal}
Log 2nd keyword
END
Log Outside loop
Second Example
FOR ${var} IN one two ${3} four ${five}
... kuusi 7 eight nine ${last}
Log ${var}
END

What would this command do if run in UNIX?

I saw this command posted somewhere, :(){ :|:& };:
What would it do if I ran it in UNIX, I don't feel like trying myself in case it does something bad
This is a fork bomb and it is very bad.
It will spawn many many processes, the number growing exponentially as each process spawns two more. They will clog your system until it falls over.
Don't run it. Its fork bomb. it will bring down your system.
From wikipedia :
/- Define the function ':' without any parameters '()' as follows:
| /- Beginning of function-block.
| | /- Load a copy of the function ':' into memory ...
| | |/- ... and pipe its output to ...
| | ||/- ... another copy of the ':'-function, which has to be loaded into memory.
| | ||| (In other words, ':|:' loads two more copies of ':', thus causing a chain-reaction)
| | |||/- Disown the functions (make them a background process), so that the children of a parent
| | |||| will not be killed when the parent gets auto-killed.
| | |||| /- End of function-block.
| | |||| |/- End of definition.
/-\| |||| ||/- Execute the function ':'. The chain-reaction begins.
:(){ :|:& };:
Here is the link http://en.wikipedia.org/wiki/Fork_bomb

Resources